I'm hoping someone can help me with a SQL select statement for the following problem:
I have the following data in a table:
date
color
01/23/2023
RED
01/23/2023
BLUE
01/23/2023
GREEN
01/23/2023
GREEN
01/23/2023
RED
01/23/2023
BLUE
01/23/2023
GREEN
01/24/2023
BLUE
01/24/2023
GREEN
01/24/2023
BLUE
01/24/2023
RED
01/25/2023
GREEN
01/25/2023
BLUE
01/25/2023
GREEN
01/25/2023
BLUE
and I would like to produce this:
date
RED
BLUE
GREEN
01/23/2023
2
2
3
01/24/2023
1
2
1
01/25/2023
0
2
2
I'll have the exact colors so I don't need that to be determined. Sorry but I don't have any idea of how to even to beginning writing this select statement.
Thanks.
SELECT date,
SUM(CASE WHEN color = 'RED' THEN 1 ELSE 0 END) AS RED,
SUM(CASE WHEN color = 'BLUE' THEN 1 ELSE 0 END) AS BLUE,
SUM(CASE WHEN color = 'GREEN' THEN 1 ELSE 0 END) AS GREEN
FROM table1
GROUP BY date
ORDER BY date;
You can use CASE WHEN SUM
SELECT
edate,
SUM (CASE WHEN color = 'RED' THEN 1 ELSE 0 END) AS RED,
SUM (CASE WHEN color = 'BLUE' THEN 1 ELSE 0 END) AS BLUE,
SUM (CASE WHEN color = 'GREEN' THEN 1 ELSE 0 END) AS GREEN
FROM tablename
GROUP BY edate
First, it would be mighty helpful if you posted your example data as "Readily Consumable Data" on future posts. Like this for this post...
--===== Create "Readily Consumable Data to help those
-- That would help you.
DROP TABLE IF EXISTS #TestTable;
GO
SELECT *
INTO #TestTable
FROM (VALUES
('01/23/2023','RED')
,('01/23/2023','BLUE')
,('01/23/2023','GREEN')
,('01/23/2023','GREEN')
,('01/23/2023','RED')
,('01/23/2023','BLUE')
,('01/23/2023','GREEN')
,('01/24/2023','BLUE')
,('01/24/2023','GREEN')
,('01/24/2023','BLUE')
,('01/24/2023','RED')
,('01/25/2023','GREEN')
,('01/25/2023','BLUE')
,('01/25/2023','GREEN')
,('01/25/2023','BLUE')
)d(date,color)
;
Giving credit where credit is certainly due, both #Learning and #Horaciux gave excellent CROSSTAB answers that do exactly what you ask.
In anticipation of what the folks that asked originally ask you for this output will likely ask of you next, you can also easily add a "DateTotal" and a "ColorTotal". CROSSTABs do make this easy. PIVOTs? No so much and I'm not going to demo that.
Here's the code to include the additional DateTotal column and ColorTotal row. I also converted the CASE statements to IIF to make things less busy. To be sure, though, IIF resolves to CASE statements behind the scenes and that means there's no performance advantage. If you hate IIF, like some do, just change them back to CASE and Bob's your uncle. :D
SELECT Date = IIF(GROUPING(date) = 1, 'Total',CONVERT(CHAR(10),date,101))
,Red = SUM(IIF(color = 'RED' ,1,0))
,Blue = SUM(IIF(color = 'BLUE' ,1,0))
,Green = SUM(IIF(color = 'GREEN',1,0))
,DateTotal = COUNT(*)
FROM #TestTable
GROUP BY date WITH ROLLUP
ORDER BY GROUPING(date),Date
;
That produces the following output...
Related
I'm trying to create a new column in my BigQuery table based on the partial match values in another column. Here is an example of what I'm trying to do. Let's say this is my table:
id
statement
123
I like green
234
I love green
456
I like orange
123
I hate yellow
What I want to do is create a new table that looks like this:
id
statement
color
123
I like green
green
234
I love green
green
456
I like orange
orange
123
I hate yellow
None
I've tried using a query like this:
SELECT ID, Statement
CASE WHEN Statement IN ('green') THEN 'green' ELSE 'None' END AS color
CASE WHEN Statement IN ('orange') THEN 'orange' ELSE 'None' END AS color
FROM `data.Table1`
but this, of course, only works if it's an exact match. How can I get a new column with a value based on a partial match like described above? Thanks in advance.
You are close:
SELECT ID, Statement,
(CASE WHEN Statement LIKE '%green%' THEN 'green'
WHEN Statement LIKE '%orange%' THEN 'orange'
ELSE 'None'
END) as color
FROM `data.Table1`;
Note: This returns the first color that is matched, which is consistent with the way that you phrased the question.
A simplified version of what I'm asking is: Say I already have a column for pedestrian jacket colors and it is very specific includes values like (canary, gold, dandelion, yellow, lemonade, sky blue, baby blue, cerulean, etc.). I want to create 2 new columns:
"Color Group" and "Light-Dark" so that I can label all of the yellow-ish jackets under Color Group yellow and I can classify all of them as light colors.
Please note that I'm working within a database product and all of the data is stored in the database I cannot create new data within the actual database. But in the reporting module, I can create columns based on existing columns. This data would only exist in the report and not in the database. Also, the way its set up I don't need the SELECT command that just happens by default but feel free to put it in your response it won't confuse me.
I've tried:
if
customer_jacket_color = "dandelion"
then
"Yellow"
Also tried it with WHEN instead of "if"
when customer_jacket_color_group = 'Yellow'
then
'light'
My expected results would take the 1 column of colors and give me 3 columns that describe the colors based on how I map the original values to the new columns.
Dandelion, Yellow, Light
Navy Blue, Blue, Dark
Mint, Green, Light...
I think you want a case expression:
select t.*,
(case when customer_jacket_color = 'dandelion' then 'Yellow'
when customer_jacket_color = 'sky blue' then 'Blue'
. . .
end) as color_group,
(case when customer_jacket_color = 'dandelion' then 'light'
when customer_jacket_color = 'sky blue' then 'dark'
. . .
end) as light_dark
from t;
I have a situation where I have 4 color columns(Color1, Color2, Color3, Color4) I need to add the values of bar codes present in all color columns when they match. Its bit complicated, I have the graphical representation here:
Color1 Color2 Color3 Color4 Barcodes
Red 1
Red 3
Red 4
Red 2
Expected Result: Total Barcodes where Color is Red=10
I am using SQL Server
Any Assistance in this would be really helpful.
EDIT: there are 320 colors in the table
I would unpivot and aggregate:
select sum(Barcodes)
from t cross apply
(values (color1), (color2), (color3), (color4)) v(color)
where color = 'Red';
If you want this for each color:
select color, sum(Barcodes)
from t cross apply
(values (color1), (color2), (color3), (color4)) v(color)
group by color;
I got data like this:
ITEM COLOR VOL
1 RED 3
2 BLUE 3
3 RED 3
4 GREEN 12
5 BLUE 3
6 GREEN 12
and I want to have the total sum of each color,
mean RED + BLUE + GREEN = 3+3+12 = 18
P.S I can't do it in sub-query since it is a part of a big query already. I am looking for a way could do it in select clause.something like
select sum(distinct(COLOR) VOL) from myTable group by COLOR
Thanks a lot!
Sum the sum of distinct, as grouped by color
select sum(sum(distinct VOL))
from MyTable
group by COLOR
Tested locally and here
One approach uses a CTE or subquery to find the mean volumes for each color. Then take the sum of all mean volumes, for all colors.
WITH cte AS (
SELECT COLOR, AVG(VOL) AS VOL -- or MIN(VOL), or MAX(VOL)
FROM yourTable
GROUP BY COLOR
)
SELECT SUM(t.VOL)
FROM cte t
sum(max(vol)) from ... group by color
will work, but it's not clear why you should need such a thing. Likely this sum can be computed (much) earlier in your query, not right at the end.
Proof of concept (on a standard Oracle schema):
SQL> select sum(max(sal)) from scott.emp group by deptno;
SUM(MAX(SAL))
-------------
10850
1 row selected.
I have a list of numbers attached to two separate columns, and I want to just return the first "match" of the two columns to get that data. I got close with this answer, but it only works with one field. I need it to work with a combination of fields. About ten second before I was ready to post.
Here's an example table "Item":
Item Color Area
Boat Red 1
Boat Red 2
Boat Blue 4
Boat Blue 5
Car Red 3
Car Red 4
Car Blue 10
Car Blue 31
And the result set returned should be:
Item Color Area
Boat Red 1
Boat Blue 4
Car Red 3
Car Blue 10
A much simpler way to do this:
select Item,
Color,
min(Area) as Area
from Item
group by Item
Color
Just use the MIN function with a GROUP BY.
SELECT Item, Color, MIN(area) AS Area
FROM Item
GROUP BY Item, Color
Output:
Item Color Area
Boat Blue 4
Boat Red 1
Car Blue 10
Car Red 3
SQL Fiddle: http://sqlfiddle.com/#!9/46a154/1/0
SQL tables represent unordered sets. Hence, there is no "first" of anything without a column specifying the ordering.
For your example results, the simplest query is:
select item, color, min(area) as area
from item i
group by item, color;
About ten seconds before I was ready to post the question, I realized the answer:
WITH summary AS (
SELECT i.item + ':' + i.color,
a.area,
ROW_NUMBER() OVER(PARTITION BY i.item + ':' + i.color,
ORDER BY i.item + ':' + i.color DESC) AS rk
FROM Item i
group by (i.item + ':' + i.color, i.Area)
SELECT s.*
FROM summary s
WHERE s.rk = 1
It's as simple as combining the two composite key fields into one field and grouping based on that. This might be a bit hackish so if anyone wants to suggest a better option I'm all for it.