Count Total Bar codes of Specific Color by fetching values from various fields when they match in SQL - sql

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;

Related

SQL Aggregation function to get concrete value

I need help with an aggregation functionality.
what I want to know is if it is possible to extract a concrete value from a grouped query on one of the columns I return, like this
STORE
fruit
color
stock
apple
red
30
apple
green
5
banana
yellow
40
berry
red
5
pear
green
5
SELECT SUM(stock), [?] FROM store GROUP BY fruit
[?] -> i need to take a concrete value, for example RED. but the SUM must have 35 in apples.
can this be done without a subquery?
Thanks
I expect this results
Column A
Column B
35
red
in this case the query does not make sense but for my personal case it does. I try to use STRING_AGG to take the data and make explode in my code, but its not the best way i think
I think you're looking for the GROUP BY clause. Try this:
SELECT SUM(stock), color
FROM store
GROUP BY color
This will return a list of all colors, and the sum of the stock for each color.
I'm not entirely clear what you mean by a "concrete value" (singlular) as there are potentially two or more values... and you did mention STRING_AGG(). Also, you omitted the "fruit" from the query, which made things a bit confusing. Nonetheless, this will get either one Color value or all color values using STRING_AGG() OR MAX() and without a sub-query:
-- the WITH is just a way to get your data into the query
;
WITH AdriansData AS
(SELECT * FROM (VALUES('apple', 'red', 30),
('apple', 'green', 5),
('banana', 'yellow', 40),
('berry', 'red', 5),
('pear', 'green', 5)
) AS X (fruit, color, stock)
)
SELECT fruit,
SUM(stock),
STRING_AGG(color, ', ') AS Colors,
MAX(color) AS JustOneColor
FROM AdriansData
GROUP BY fruit

Set value based on count distinct

Let's say that I have the following data on tbl:
Label | Color
X | color1
X | color1
Y | color1
Y | color2
The sample output should be:
X | color1
Y | misc
So basically, if the respective label only has one type of color I want it to be that type, else I want it to say misc.
I did the following which didn't work as I wanted, which the next step would be applying a case into the count:
select label,count(distinct color) from #tbl
group by label,color
you can use MAX or MIN to get the single value to use where appropriate.
And should be grouping just by label
select label,
case when count(distinct color) = 1 THEN MAX(color) ELSE 'misc' END
from #tbl
group by label
It will generally be more efficient though to check if max equals min rather than doing a distinct count
select label,
case when MAX(color) = MIN(color) THEN MAX(color) ELSE 'misc' END
from #tbl
group by label
There isn't much to choose between the two in efficiency if you have an index on label, color but if you only have an index on (label) INCLUDE (color) or have no useful index at all the MAX/MIN approach will have to do less work (just needs a single grouping operation on label and to keep track of two values within each group - not identify the number of unique values in each group)

How to create a SQL column whose values depend on (map to) the values of an existing lookup column?

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;

Sum of distinct items values Oracle SQL

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.

SQL - Select top item from a grouping of two columns

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.