I have a table
t:flip `dt`id`data ! (`d1`d1`d2`d2`d3`d3; 0 1 0 1 0 1; 100 200 100 300 0 200)
and from some other query, I have a table
s:flip `dt`id ! (`d1`d2`d2`d3; 0 0 1 1)
How can I select from t such that it returns all entries where the combination of dt and id are in s, so return
flip `dt`id`data ! (`d1`d2`d2`d3; 0 0 1 1; 100 100 300 200)
You can use in on table to table ops so just create a table from your required columns in t and use in to search s for the corresponding records. As long as the table columns and types from the left argument and right argument are the same, then in will produce a boolean list as expected.
q)select from t where ([]dt;id) in s
dt id data
----------
d1 0 100
d2 0 100
d2 1 300
d3 1 200
Related
I have a table with a shipment_id, no_of_boxes, and no_of_pallets as shown below.
shipment_id
no_of_boxes
no_of_pallets
1
23
0
1
45
0
1
0
1
2
3
0
2
165
0
2
0
10
I want to sum the no_of_boxes, and no_of_pallets columns against their respective shipment_id. The columns no_of_boxes, and no_of_pallets are COUNT derived columns (calculated from a different table with JOINS).
I tried writing a subquery for this but didn't help. Below subquery is for no_of_boxes, a similar query was written for no_of_pallets.
SELECT SUM(no_of_boxes)
FROM (SELECT COUNT(si.shipment_item_id) AS no_of_boxes
FROM shipment_item AS si
JOIN shipment_item AS si
ON si.shipment_order_systemid = sho.system_id
JOIN shipping_unit AS su
ON su.system_id = si.shipping_unit_systemid
WHERE su.unit LIKE 'BOX'
GROUP BY si.shipment_item_id,
su.unit) t
My desired result is:
shipment_id
no_of_boxes
no_of_pallets
1
68
1
2
168
10
To get the result you want, use the following query:
SELECT shipment_id, sum(no_of_boxes), sum(no_of_pallets)
FROM shipments
GROUP BY shipment_id;
I would like to get all the groups that have a distinct price of 0 from my table, IE only if all prices are 0 in that group should it be returned.
My query & table look something like this.
tab:([]grp:`a`b`c`c`a`a`a;price:0 20 0 1 0 0 0)
select grp from tab where distinct price = 0
The output should only be `a since `a is the only group where all prices are 0.
Using an fby is one way to achieve the result here.
q)tab:([]grp:`a`b`c`c`a`a`a;price:0 20 0 1 0 0 0)
q)select from tab where 0=(max;abs price)fby grp
grp price
---------
a 0
a 0
a 0
a 0
q)distinct exec grp from tab where 0=(max;abs price)fby grp
,`a
Another approach:
q)where exec all 0=price by grp from tab
,`a
I want to update a table with the sum of a second table
This is the table 'x' that I want to update. Has a starting value and a closing value:
id
op_date
initial_value
end_value
1
2020-02-01
0
0
1
2020-02-02
0
0
2
2020-02-01
0
0
2
2020-02-02
0
0
The table 'y' save the values of the day:
id
op_date
value_day
1
2020-01-29
500
1
2020-02-01
100
1
2020-02-02
200
2
2020-01-29
750
2
2020-02-01
100
2
2020-02-02
250
I want the result to look like this:
id
op_date
initial_value
end_value
1
2020-02-01
500
600
1
2020-02-02
600
800
2
2020-02-01
750
850
2
2020-02-02
850
1100
I tried this script, but the process just runs it and doesn't finish it:
UPDATE x
SET
initial_value= (select sum(y.value_day)
from public.y where
y.op_date > '2020-11-01' and y.op_date < x.op_date
and y.id = x.id),
end_value= (select sum(y.value_day)
from public.y where
y.op_date between '2020-11-01' and x.op_date
and y.id = x.id);
You can use window function. To understand window function more you can look this link.
At first i am writing query to select the value.
select id,op_date,
sum(value_day) over (
partition by y.id
rows between unbounded preceding and current row
)-value_day as initial_value,
sum(value_day) over (
partition by y.id
rows between unbounded preceding and current row
) as end_value
from y
;
This is your update query.
UPDATE x
set initial_value=s_statement.initial_value,
end_value=s_statement.end_value
from
(select id,op_date,
sum(value_day) over (
partition by y.id
rows between unbounded preceding and current row
)-value_day as initial_value,
sum(value_day) over (
partition by y.id
rows between unbounded preceding and current row
) as end_value
from y) s_statement
where x.id=s_statement.id
and x.op_date=s_statement.op_date
;
Let me know if its ok with you.
I have a sql problem (on Redshift) where I need to get the value from column index for each id in column id based on max value in column final_score and put this value in a new column fav_index. score2 equals to the value of score1 where index n = index n + 1, for example, for id = abc1, index = 0 and score1 = 10 the value of score2 will be the value of score1 where index = 1 and the value of final_score is the difference between score1 and score2.
It's easier if you look at below table score. This table score is a result of a sql query which is shown later below.
id index score1 score2 final_score
abc1 0 10 20 10
abc1 1 20 45 25
abc1 2 45 (null) (null)
abc2 0 5 10 5
abc2 1 10 (null) (null)
abc3 0 50 30 -20
abc3 1 30 (null) (null)
So, the resulting table containing column fav_index should look like this:
id index score1 score2 final_score fav_index
abc1 0 10 20 10 0
abc1 1 20 45 25 1
abc1 2 45 (null) (null) 0
abc2 0 5 10 5 0
abc2 1 10 (null) (null) 0
abc3 0 50 30 -20 0
abc3 1 30 (null) (null) 0
Below is the script to generate table score from table story:
select
m.id,
m.index,
max(m.max) as score1,
fmt.score2,
round(fmt.score2 - max(m.max), 1) as final_score
from
(select
sv.id,
case when sv.story_number % 2 = 0 then cast(sv.story_number / 2 - 1 as int) else cast(floor(sv.story_number/2) as int) end as index,
max(sv.score1)
from
story as sv
group by
sv.id,
index,
sv.score1
order by
sv.id,
index
) as m
left join
(select
sv.id,
case when sv.story_number % 2 = 0 then cast(sv.story_number / 2 - 1 as int) else cast(floor(sv.story_number/2) as int) end as index,
max(score1) as score2
from
story as sv
group by
id,
index
) as fmt
on
m.id = fmt.id
and
m.index = fmt.index - 1
group by
m.id,
m.index,
fmt.score2
Table story is as below:
id story_number score1
abc1 1 10
abc1 2 10
abc1 3 20
abc1 4 20
abc1 5 45
abc1 6 45
The only solution I can think of is to do something like,
select id, max(final_score) from score group by id
and then join it back to the long script above (which was used to generate table score). I really want to avoid writing such a long script to get just 1 extra column of information that I need.
Is there a better way to do this?
Thank you!
Update: answer in mysql is also accepted. thanks!
After spending more hours on this and asking people around, I finally figured out a solution by referring to this window function documentation - PostgreSQL https://www.postgresql.org/docs/9.1/static/tutorial-window.html
I basically added 2 x select statements at the top and 1 x where statement at the very bottom. The where statement is to take care of the rows where final_score = null because otherwise the rank() function will rank them as 1.
My code then becomes:
select
id, index, final_score, rank, case when rank = 1 then index else null end as fav_index
from
(select
id, index, final_score, rank() over (partition by id order by final_score desc)
from
(select
m.id,
m.index,
max(m.max) as score1,
fmt.score2,
round(fmt.score2 - max(m.max), 1) as final_score
from
(select
sv.id,
case when sv.story_number % 2 = 0 then cast(sv.story_number / 2 - 1 as int) else cast(floor(sv.story_number/2) as int) end as index,
max(sv.score1)
from
story as sv
group by
sv.id,
index,
sv.score1
order by
sv.id,
index
) as m
left join
(select
sv.id,
case when sv.story_number % 2 = 0 then cast(sv.story_number / 2 - 1 as int) else cast(floor(sv.story_number/2) as int) end as index,
max(score1) as score2
from
story as sv
group by
id,
index
) as fmt
on
m.id = fmt.id
and
m.index = fmt.index - 1
group by
m.id,
m.index,
fmt.score2)
where
final_score is not null)
And the result is as follows:
id index final_score rank fav_index
abc1 0 10 2 (null)
abc1 1 25 1 1
abc2 0 5 1 0
abc3 0 -20 1 0
Result is slightly different than what I stated in the question, however, the fav_index for each id is identified and this is what I needed really. Hope this might help someone. Cheers
We are trying to output for each customer column should have 12 budgeted row entries for every month.
Scenario 1:
ie. Turn table data :
Name BudMnt1|BudMnt2|BudMnt3
cust1 0 0 0
cust2 0 0 0
cust3 2418 0 0
cust4 0 416 198
into this :
Name cust1| cust2| cust3| cust4
BudMnt1 0 0 24180 0
BudMnt2 0 0 0 416
BudMnt3 0 0 0 198
Scenario 2:
Includes Scenario 1 column as Budget+ additional column is sales solumn here
so, it becomes two column budget ,sales which needs to unpivot on single query structure.
ie. Turn table data :
Name JanSales|FebSales|MarSales
cust1 0 0 0
cust2 0 0 0
cust3 0 0 3
cust4 2 0 0
into this :
Name cust1|cust2|cust3|cust4
JanSales 0 0 0 2
Feb Sales 0 0 0 0
Mar Sales 0 0 3 0
Any HELP would be much appreciated !
This link may help you as a reference to your question:
https://social.msdn.microsoft.com/Forums/office/en-US/04346f7c-0923-432d-83c3-22bf759dea22/transpose-data-from-columns-into-rows-using-sql
This code works fine. Tasted it on sql server 2012.
SELECT NAME ,
budmtn ,
cust
INTO #temptable
FROM ( SELECT *
FROM tbl1
) AS result UNPIVOT ( cust FOR budmtn IN ( budmtn1, budmtn2, budmtn3 ) ) AS unpivotedtable
SELECT budmtn ,
cust1 ,
cust2 ,
cust3 ,
cust4
FROM #temptable PIVOT( SUM(cust) FOR NAME IN ( cust1, cust2, cust3, cust4 ) ) AS result