Trying to group items into different categories based on a specific field's value - sql

i cant quite figure out how to put this into a simple question, so I'll explain what I have and what I need to do.
Table A
|..ItemNum..|..ItemUse..|..SubC..|..MainC..|
|..123..|..B..|..AAA..|..QQQ..|
|..456..|..J..|..BBB..|..QQQ..|
|..123..|..D..|..DDD..|..RRR..|
|..789..|..C..|..CCC..|..WWW..|
|..345..|..W..|..EEE..|..TTT..|
|..678..|..B..|..FFF..|..YYY..|
I need to make a list of ItemNum and MainC that are grouped into 3 categories:
B / C / D = 1
<anything else> = 2
B / C / D & <anything else> = 3
So my results would be:
|..MainC..|..Group..|
|..QQQ..|..3..|
|..RRR..|..1..|
|..WWW..|..1..|
|..TTT..|..2..|
|..YYY..|..1..|
I've got an iif setup that takes care of groups 1 and 2, but cant figure out how to get the values in MainC to come out with Group 3.
Any ideas?

I don't understand your explanation ( especially the mapping to 3 ) but here's a shot:
select MainC, case when ItemUse in ('B','C','D') then 1
else 2
end as group
from A

Related

SQL Server 'AS' alias unexpected syntax

I've come across following T-SQL today:
select c from (select 1 union all select 1) as d(c)
that yields following result:
c
-----------
1
1
The part that got me confused was d(c)
While trying to understand what's going on I've modified T-SQL into:
select c, b from (select 1, 2 union all select 3, 4) m(c, b)
which yields following result:
c b
----------- -----------
1 2
3 4
It was clear that d & m are table reference while letters in brackets c & b are reference to columns.
I wasn't able to find relevant documentation on msdn, but curious if
You're aware of such syntax?
What would be useful use case scenario?
select c from (select 1 union all select 1) as d(c)
is the same as
select c from (select 1 as c union all select 1) as d
In the first query you did not name the column(s) in your subquery, but named them outside the subquery,
In the second query you name the column(s) inside the subquery
If you try it like this (without naming the column(s) in the subquery)
select c from (select 1 union all select 1) as d
You will get following error
No column name was specified for column 1 of 'd'
This is also in the Documentation
As for the usage, some like to write it the first method, some in the second, whatever you prefer. It's all the same
An observation: Using the table constructor values gives you no way of naming the columns, which makes it neccessary to use column naming after the table alias:
select * from
(values
(1,2) -- can't give a column name here
,(3,4)
) as tableName(column1,column2) -- gotta do it here
You've already had comments that point you to the documentation of how derived tables work, but not to answer you question regarding useful use cases for this functionality.
Personally I find this functionality to be useful whenever I want to create a set of addressable values that will be used extensively in your statement, or when I want to duplicate rows for whatever reason.
An example of addressable values would be a much more compelx version of the following, in which the calculated values in the v derived table can be used many times over via more sensible names, rather than repeated calculations that will be hard to follow:
select p.ProductName
,p.PackPricePlusVAT - v.PackCost as GrossRevenue
,etc
from dbo.Products as p
cross apply(values(p.UnitsPerPack * p.UnitCost
,p.UnitPrice * p.UnitsPerPack * 1.2
,etc
)
) as v(PackCost
,PackPricePlusVAT
,etc
)
and an example of being able to duplicate rows could be in creating an exception report for use in validating data, which will output one row for every DataError condition that the dbo.Product row satisfies:
select p.ProductName
,e.DataError
from dbo.Products as p
cross apply(values('Missing Units Per Pack'
,case when p.SoldInPacks = 1 and isnull(p.UnitsPerPack,0) < 1 then 1 end
)
,('Unusual Price'
,case when p.Price > (p.UnitsPerPack * p.UnitCost) * 2 then 1 end
)
,(etc)
) as e(DataError
,ErrorFlag
)
where e.ErrorFlag = 1
If you can understand what these two scripts are doing, you should find numerous examples of where being able to generate additional values or additional rows of data would be very helpful.

How to Quickly Flatten a SQL Table

I'm using Presto. If I have a table like:
ID CATEGORY VALUE
1 a ...
1 b
1 c
2 a
2 b
3 b
3 d
3 e
3 f
How would you convert to the below without writing a case statement for each combination?
ID A B C D E F
1
2
3
I've never used Presto and the documentation seems pretty thin, but based on this article it looks like you could do
SELECT
id,
kv['A'] AS A,
kv['B'] AS B,
kv['C'] AS C,
kv['D'] AS D,
kv['E'] AS E,
kv['F'] AS F
FROM (
SELECT id, map_agg(category, value) kv
FROM vtable
GROUP BY id
) t
Although I'd recommend doing this in the display layer if possible since you have to specify the columns. Most reporting tools and UI grids support some sort of dynamic pivoting that will create columns based on the source data.
My 2 cents:
If you know "possible" values:
SELECT
m['web'] AS web,
m['shopping'] AS shopping,
m['news'] AS news,
m['music'] AS music,
m['images'] AS images,
m['videos'] AS videos,
m[''] AS empty
FROM (
SELECT histogram(data_tab) AS m
FROM datahub
WHERE
year = 2017
AND month = 5
AND day = 7
AND name = 'search'
) searches
No PIVOT function (yet)!

SQL list multiple Duplicates

running a SQL query in access that is giving me matches where A = record 1, and B also = record 1 , C= record 2 and D E and F also = record 2.
I want my results to display (only max Value)
B =record 1
F= record 2. ( this is a matching query)
basically i want to eliminate duplicates and select "distinct" does not seem to be working for me.
SELECT
FEED_2.ID AS FEED_2_ID,
FEED_3.field_ID,
FEED_3.ID AS FEED_3_ID
FROM FEED_2 INNER JOIN FEED_3 ON FEED_2.[field_ID] = FEED_3.[field_ID]
order by FEED_3.ID
im getting results where feed 2 ID #1,3, and 5 all equal feed 3 - ID #1
i only want feed 2, #5 = feed 3 #1. no Dupes
sorry - hope that helps
It's a shot in the dark but, is something like this you are looking for?
SELECT max(Column_With_ABCDEF), Column_With_record from TABLE_NAME GROUP BY Column_With_record;
If this is not what you are asking for, please do edit your question with your table schema and/or the query you are using so we can help.
---------------- EDIT ----------------
Ok so you can try this:
Select max(FEED_2_ID), field_ID , FEED_3_ID
from (
SELECT FEED_2.ID AS FEED_2_ID, FEED_3.field_ID As field_ID, FEED_3.ID AS FEED_3_ID
FROM FEED_2 INNER JOIN FEED_3
ON FEED_2.[field_ID] = FEED_3.[field_ID]
)
GROUP BY FEED_3_ID, field_ID
ORDER BY FEED_3_ID
The main select is going to group the result from the subquery, that way you should not get duplicated values.
Hope this help

SQL query for aggregate on multiple rows

I have data in a table like following
Name indicator
A 1
A 2
A 3
B 1
B 2
C 3
I want to get count of Names, for which both indicator 1,2 exists. In the preeceding example, this number is 2 (A & B both have indicator as 1, and 2).
The data I am dealing with is moderately large, and i need to get the similar information of some other permutations of (pre defined ) indicators (which i can change, once i get base query).
Try this:
SELECT Name
FROM Tablename
WHERE indicator IN(1, 2)
GROUP BY Name
HAVING COUNT(DISTINCT indicator) = 2;
See it in action here:
SQL Fiddle Demo

Select non-matching record in same table - SQL

What I am tying to do sounds simple, but cant figure it out. I have a table with a report_number field and a report_type field. The report_number field can have the same "report number" in it as well as the report_type field. I will give some data to better explain what I need to do.
report_number report_type
1 A
2 A
2 B
1 A
3 A
3 A
3 A
4 C
4 C
I need to query for reports that = 'A', but not the SAME report number that also has a report type B associated with it. The results that I would like to get is report #s 1 and 3.
The report number can have different report_types associated with it.
Thanks!
try:
select distinct(report_number)
from reports
where report_type='A' and report_number not in (select report_number from reports where report_type='B')
SELECT DISTINCT a.Report_Number
FROM YourTable a
LEFT JOIN YourTable b
ON a.Report_Number = b.Report_Number
AND a.Report_Type <> b.Report_Number
-- OPTIONAL
AND b.Report_Type = 'B'
WHERE b.Report_Type IS NULL
-- OPTIONAL
AND a.Report_Type = 'A'
EDIT
So far 3 solutions have been posted all adopting a different approach. Check this Link to see which one will suit your RDBMS.