T-SQL query results based on count [closed] - sql-server

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
Improve this question
Given the table above how could I achieve a result where I would only see rows where A has a category, so for example I would see all the rows for CARS AND BIKES but not SCOOTERS because A does not have SCOOTER category.
The 2nd result I would to achieve is just so see rows where there are > 3 distinct OrgNames for a Category. So for example I would only return rows for BIKES and SCOOTERS because there are more than 3 OrgNames per Category.
Thank you in advance

I think I understand the types of queries you're wanting to create.
Take a look at the code below:
DECLARE #ExampleData TABLE (
OrgName nvarchar(1),
Category nvarchar(10)
)
INSERT INTO #ExampleData (OrgName, Category)
SELECT DISTINCT
OrgName,
Category
FROM (SELECT
'A' AS OrgName,
'CARS' AS Category
UNION ALL
SELECT
'B' AS OrgName,
'CARS' AS Category
UNION ALL
SELECT
'C' AS OrgName,
'CARS' AS Category
UNION ALL
SELECT
'A' AS OrgName,
'BIKES' AS Category
UNION ALL
SELECT
'D' AS OrgName,
'BIKES' AS Category
UNION ALL
SELECT
'E' AS OrgName,
'BIKES' AS Category
UNION ALL
SELECT
'F' AS OrgName,
'BIKES' AS Category
UNION ALL
SELECT
'Z' AS OrgName,
'SCOOTERS' AS Category
UNION ALL
SELECT
'G' AS OrgName,
'SCOOTERS' AS Category
UNION ALL
SELECT
'H' AS OrgName,
'SCOOTERS' AS Category
UNION ALL
SELECT
'I' AS OrgName,
'SCOOTERS' AS Category
UNION ALL
SELECT
'J' AS OrgName,
'SCOOTERS' AS Category) data
/*
View full recordset
*/
SELECT
e.*
FROM #ExampleData e
ORDER BY e.Category ASC, e.OrgName ASC
/*
Option 1: Only rows where at least 1 category has an OrgName = 'A'
*/
SELECT
e.*
FROM #ExampleData e
INNER JOIN (SELECT DISTINCT
e.Category
FROM #ExampleData e
WHERE e.OrgName = 'A') cat
ON cat.Category = e.Category
ORDER BY e.Category ASC, e.OrgName ASC
/*
Option 2: Only see rows where therere are >3 Org Names per category
*/
SELECT
e.*
FROM #ExampleData e
INNER JOIN (SELECT DISTINCT
e.Category,
COUNT(DISTINCT e.OrgName) AS Count
FROM #ExampleData e
GROUP BY e.Category) cat
ON cat.Category = e.Category
AND cat.Count > 3
ORDER BY e.Category ASC, e.OrgName ASC
It gives the output below:
If this solves your question, please accept this answer and upvote for other people who may have this same question in the future.

Related

Sqlite display table with informations about the databas

They are asking me to write a query that display the following table:
Select each table as a string
Select the number of attributes as an integer (count the number of attributes per table).
Select the number of rows using the COUNT(*) function
Use the compound-operator UNION ALL to bind these rows together.
How do I do that?
I knew that for getting the name of each table I have to use
SELECT name AS table_name
FROM sqlite_schema
WHERE type = 'table'
but the rest is a mistery to me.
Would you help me?
Thank you!!!
Here you can find the database
Just had the same question, and the answer boiled down to 'manually' (looking at the schema visualisation or the aforementioned query for inputs). >_<
SELECT 'Customers' AS table_name,
13 AS number_of_attribute,
COUNT(*) AS number_of_row
FROM Customers
UNION ALL
SELECT 'Products' AS table_name,
9 AS number_of_attribute,
COUNT(*) AS number_of_row
FROM Products
UNION ALL
SELECT 'ProductLines' AS table_name,
4 AS number_of_attribute,
COUNT(*) AS number_of_row
FROM ProductLines
UNION ALL
SELECT 'Orders' AS table_name,
7 AS number_of_attribute,
COUNT(*) AS number_of_row
FROM Orders
UNION ALL
SELECT 'OrderDetails' AS table_name,
5 AS number_of_attribute,
COUNT(*) AS number_of_row
FROM OrderDetails
UNION ALL
SELECT 'Payments' AS table_name,
4 AS number_of_attribute,
COUNT(*) AS number_of_row
FROM Payments
UNION ALL
SELECT 'Employees' AS table_name,
8 AS number_of_attribute,
COUNT(*) AS number_of_row
FROM Employees
UNION ALL
SELECT 'Offices' AS table_name,
9 AS number_of_attribute,
COUNT(*) AS number_of_row
FROM Offices;

SQL - Find orders with certain item combo(from another table)

I have these 3 tables - CodesetList, Rule, Order:
In the first row of the Rule table, if a client ordered any of the CODE_ID under CODESET_ID=12 and any of the CODE_ID under CODESET_ID = 7 on the same service date(DAYS_FROM_Service=0), I want to find the transaction in Order table. Ultimately, if a client orders a combination of two items(Rule table), we want to deny the order according to the rule table.
Sorry, I'm bad at explaining this.
Rule:
CodesetList(note that ABC0274 is under Codeset_ID 9 & 10 and this is expected):
Order:
-- Create CodsetList table
SELECT '7' as CODESET_ID, 'ABC0210' as CODE_ID INTO #CodesetList UNION ALL
SELECT '8','ABC0220' UNION ALL
SELECT '8','ABC0230' UNION ALL
SELECT '8','ABC0240' UNION ALL
SELECT '8','ABC0250' UNION ALL
SELECT '8','ABC0260' UNION ALL
SELECT '9','ABC0270' UNION ALL
SELECT '9','ABC0272' UNION ALL
SELECT '9','ABC0274' UNION ALL
SELECT '9','ABC0273' UNION ALL
SELECT '10','ABC0274' UNION ALL
SELECT '11','ABC0277' UNION ALL
SELECT '12','ABC0330' UNION ALL
SELECT '83','ABC5110' UNION ALL
SELECT '83','ABC5120' UNION ALL
SELECT '83','ABC5130' UNION ALL
SELECT '83','ABC5140'
-- Create Rule table
SELECT '12' as TARGET_CODESET_ID, '7' as DENIAL_CODESET_ID, '2' as DIRECTION_FROM_DOS, '0' as DAYS_FROM_Service INTO #Rule UNION ALL
SELECT '83','7','1','365' UNION ALL
SELECT '7','8','2','0' UNION ALL
SELECT '7','9','2','0'
-- Create Order table
SELECT 'C3340' as ClientID, CAST('2019-10-12' AS DATE) as Service_Date, 'ABC0210' as CODE_ID INTO #Order UNION ALL
SELECT 'C3340',CAST('2019-10-12' AS DATE),'ABC0220' UNION ALL
SELECT 'C3340',CAST('2018-10-23' AS DATE),'ABC0272' UNION ALL
SELECT 'C3340',CAST('2019-10-09' AS DATE),'ABC0220' UNION ALL
SELECT 'C7646',CAST('2019-11-07' AS DATE),'ABC5110' UNION ALL
SELECT 'C7646',CAST('2019-05-07' AS DATE),'ABC0210' UNION ALL
SELECT 'C5376',CAST('2018-12-02' AS DATE),'ABC8411' UNION ALL
SELECT 'C5376',CAST('2018-10-18' AS DATE),'ABC8411' UNION ALL
SELECT 'C5376',CAST('2018-08-06' AS DATE),'ABC8161' UNION ALL
SELECT 'C9873',CAST('2019-01-06' AS DATE),'ABC6517' UNION ALL
SELECT 'C9873',CAST('2019-01-28' AS DATE),'ABC7784' UNION ALL
SELECT 'C9873',CAST('2019-03-05' AS DATE),'ABC8110'
Here's my poor attempt.
It only addresses one of the rules (row 3 from Rule table: Target=7, Denial=8)
And it also ignores the Days_From_Service rule.
SELECT *
FROM (SELECT *
FROM #Order AS o
WHERE o.CODE_ID IN(SELECT CODE_ID FROM #CodesetList WHERE CODESET_ID=7)) AS T
INNER JOIN
(SELECT *
FROM #Order AS o
WHERE o.CODE_ID IN(SELECT CODE_ID FROM #CodesetList WHERE CODESET_ID=8)) AS D ON T.ClientID=D.ClientID AND T.Service_Date=D.Service_Date;

Transforming and repeating multiple rows

I have a table that has two IDs within it named FamilyID and PersonID. I need to be able to repeat these rows with all combinations, as the below screenshot shows noting that each of the numbers get an extra row.
Here is some SQL to create the table with some sample data. There is no set number of occurrences that could occur.
Anyone aware of how we could be achieved?
CREATE TABLE #TempStackOverflow
(
FamilyID int,
PersonID int
)
insert into #TempStackOverflow
(
FamilyID,
PersonID
)
select
1012,
1
union
select
1013,
1
union
select
1014,
1
union
select
1015,
2
union
select
14774,
3
union
select
1019,
5
I understand that you need some sort of a complete list of matches within groups, but honestly, it would be much better if you would explain the business context, using plain English, in the first place.
The following query seems to produce your sample result:
with cte as (
select a.FamilyID, a.PersonID, a.PersonID as [GroupId] from #TempStackOverflow a
union all
select b.PersonID, b.FamilyID, b.PersonID from #TempStackOverflow b
)
select distinct c.FamilyID, s.PersonID
from cte c
inner join cte s on s.GroupId = c.GroupId
where c.FamilyID != s.PersonID;
Here is the simplest version I can come up with that groups the items by PersonId, as you do above. Obviously if you don't want that, then you can remove the outer query.
SELECT FamilyId,
PersonID
FROM (
SELECT FamilyId, PersonId, PersonID as SortBy
FROM #TempStackOverflow t1
UNION
SELECT PersonId, FamilyId, PersonId as SortBy
FROM #TempStackOverflow t1
UNION
SELECT t1.FamilyID, t2.FamilyID, t1.PersonID as SortBy
FROM #TempStackOverflow t1
FULL OUTER JOIN #TempStackOverflow t2
ON t1.PersonID = t2.PersonID
WHERE t1.FamilyID != t2.FamilyID
) as Src
ORDER BY SortBy

Subquery distinct field

Hello I am learning to write sql queries and I am trying to query a ledger table to SELECT a field "ENCID" where there are more than 4 distinct values in a separate file "TDATE" for each distinct ENCID.
Then filter by a 3rd field "ITEMTYPE"
This is what I have:
SELECT
[ENCID]
,[PATIENTID]
,[ITEMTYPE]
,[Service Date]
,[Transaction Date]
,[Trans]
,[PracticeName]
FROM TABLE1
WHERE ITEMTYPE = 'S'
AND ENCID IN (SELECT ENCID FROM TABLE1 WHERE Count(Distinct [Transaction Date]) >4
AND ITEMTYPE = 'S')
I am getting this error "DataSource.Error: Microsoft SQL: An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference."
Try this instead:
SELECT
[ENCID]
,[PATIENTID]
,[ITEMTYPE]
,[Service Date]
,[Transaction Date]
,[Trans]
,[PracticeName]
FROM TABLE1
WHERE ITEMTYPE = 'S'
AND ENCID IN (
SELECT ENCID
FROM TABLE1
WHERE ITEMTYPE = 'S'
GROUP BY ENCID
HAVING Count(Distinct [Transaction Date]) >4
AND MAX ([Transaction Date]) - MIN ([Transaction Date]) > 60
)
Generally, aggregate functions can only be used in SELECT, HAVING, and ORDER BY clauses (as WHERE determines exactly which records are being aggregated).
What the error message is surprisingly elaborating on is the unique cases where WHERE may contain an aggregate function. Such as this:
SELECT a.id
FROM a
GROUP BY a.id
HAVING a.id IN (
SELECT b.a_id
FROM b
WHERE b.total = COUNT(a.something)
)

How to UNION parts of different sql

I have 4 parts, each part is made out of 2 select statement. I need the 1st 2 part to be UNION'd with the 2nd part. Each part contains its own ORDER BY. I need the results to appear 1st part first and followed by the 2nd part. Only each part is sorted but not the overall result set.
(select col1,col2,col3,col4,col5 from tableA where col1 = 'x'
UNION ALL
select col1,col2,col3,col4,col5 from tableB where col1 = 'x'
ORDER BY Col3) --1st part ends here
--now I need to UNION the 2nd part
UNION ALL
(select col1,col2,col3,col4,col5 from tableA where col1 <> 'x'
UNION ALL
select col1,col2,col3,col4,col5 from tableB where col1 <> 'x'
ORDER BY Col3) --2nd part ends here
I tried wrapping each select in the SELECT * FROM (... but I'm having issues with ORDER BY. Just can't seem to get the syntax right.
Just add a column for this purpose:
select col1,col2,col3,col4,col5, ord = 1 from tableA where col1 = 'x'
UNION ALL
select col1,col2,col3,col4,col5, ord = 1 from tableB where col1 = 'x'
UNION ALL
select col1,col2,col3,col4,col5, ord = 2 from tableA where col1 <> 'x'
UNION ALL
select col1,col2,col3,col4,col5, ord = 2 from tableB where col1 <> 'x'
ORDER BY ord, Col3
The ORDER BY applies over the whole result set, after the UNION. See Example C: https://msdn.microsoft.com/en-us/library/ms180026%28v=sql.110%29.aspx
You can't have the ORDER BY in the queries within the UNION.

Resources