Dynamically Table Name in Query based on Count - sql-server-2012

I would appreciate some suggestions on generating Dynamic Query based on count from my first Query.
For Example: In 757 BTID, We found Max Count of records so it should be our first table in the second Query.
Similarly 706 will be 2nd, 788-3rd, 715 will be 4th table in second query depending on Count.
This Will be different for each user as count is different
First Query:
SELECT btid, COUNT(*) FROM dbo.PERSON_EXPANDED
WHERE PID=31226 AND BTID IN (757,706,788,715)
GROUP BY btid
First Query Results:
757 15
706 14
788 12
715 11
Second Query:
SELECT *
FROM dbo.PERSON_EXPANDED E757
INNER JOIN dbo.PERSON_EXPANDED E706 ON E757.PID=E706.PID AND E706.BTID=706 AND E757.EffectiveDate BETWEEN E706.EffectiveDate AND E706.ExpirationDate
INNER JOIN dbo.PERSON_EXPANDED S788 ON E757.PID=S788.PID AND S788.BTID=788 AND E757.EffectiveDate BETWEEN S788.EffectiveDate AND S788.ExpirationDate
INNER JOIN dbo.PERSON_EXPANDED S715 ON E757.PID=S715.PID AND S715.BTID=715 AND E757.EffectiveDate BETWEEN S715.EffectiveDate AND S715.ExpirationDate
INNER JOIN dbo.EMPLOYEE E ON P.PID=E757.PID
WHERE E757.BTID=757
AND E.PID=31226
ORDER BY E757.EffectiveDate
Thank you...

Related

Single query has 359 results but cte with multi table left join has 396 results. Why?

I am working with a query and 2 tables. This first query
SELECT * FROM B_WORKERACTIVITY
WHERE COURTCASENO IS NULL
AND WORKCOMMENT IS NOT NULL
gives 359 results. When I left join 2 tables to the query with a cte I get 396 results. I want to match the 2 tables to the query so that I only have 359 results. Below is what I've tried doing.
WITH cte AS (SELECT * FROM B_WORKERACTIVITY
WHERE COURTCASENO IS NULL
AND WORKCOMMENT IS NOT NULL )
SELECT
cte.*,
a.indssn,
i.firstname,
i.lastname
FROM cte LEFT JOIN TBLASSOC a
ON cte.REFERRALNO = a.REFERRALNO
LEFT JOIN TBLINDIVIDUALS i
ON i.INDSSN = a.INDSSN ;

how to find the rows not matched by the left join and perform some operations on top of it in sql server?

I'm trying to delete using left join from my sql server studio and my question is how do i get the list of ids that are getting deleted as part of the left join also i would like to compare the difference between the sum from both the tables
Table A:
ID NAME LOC SUM
4 abc NY 500
5 seq CA 100
15 juv TX 120
Table B:
ID NAME LOC SUM INFO
5 seq CA 90 x
18 jay AL 94 x
15 juv CL 190 x
I want to get to the number of rows that are getting removed as part of the left join and i want to see the difference in the sum
DELETE MYDB
FROM MYDB.A
LEFT JOIN MYDB.B
ON A.ID=B.ID
WHERE A.ID=B.ID
It is not clear why you would be using a LEFT JOIN for the JOIN. Your WHERE clause -- which is otherwise redundant -- is turning the outer join into an inner join.
I would suggest using exists:
delete from mydb.a
where exists (select 1 from mydb.b where b.id = a.id);
For a count, you can use:
select count(*)
from mydb.a
where exists (select 1 from mydb.b where b.id = a.id);
Do note: If you run these as two separate operations, the underlying data can change between the operations.
After running the delete, you can use ##ROWCOUNT to get the number of records deleted.

unable to join 3 tables in SQL

I am lost in joining 3 tables.
I have 3 tables:
Table with Events
Table with date range
Table with reservation count for an event on a date
Now I want to create a timeline so that for every event I have a date range with for every day a count of reservations (or 0 if there are none).
See the SQL Fiddle example
Now the issue is that I can select all records from date range and events but I cannot join the reservation table together with it to select the count of reservation on that day. I need it to create a graph of last x days for an event with the reservationcount on those days.
Expected output would be that for every date (2017-01-01,2017-01-02) I have a list of events(1,2,3..) and the reservationcount on that day (or if there is no matching reservationcount record, 0)
How to do that?
2017-01-01 1 0
2017-01-02 1 65
2017-01-03 1 345
2017-01-04 1 0
2017-01-05 1 0
2017-01-06 1 0
In your sample example there is no direct link between Events and EventDate, so if you want to attach all your events to every available date you need to have a Cartesian Product (cross join) between these tables.
There may or may not be a reservation on a specific date and event, so you need a LEFT JOIN with the reservation table.
Following query should give you the desired output.
SELECT SelDate,EV.EventId, ISNULL(ResCount,0) as ResCount FROM
EventDates ED
INNER JOIN Events EV ON 1=1
LEFT JOIN Reservations RES ON ED.SelDate = RES.EventDate AND EV.EventId=RES.EventId
Or you can also write it as
SELECT ED.*, ISNULL(ResCount,0) as ResCount FROM
(
SELECT SelDate, EventId
FROM EventDates ,Events
) ED
LEFT JOIN Reservations RES ON ED.SelDate = RES.EventDate AND ED.EventId=RES.EventId
You were close, but used the wrong outer join and missed a condition.
Select EventDates.SelDate,Events.EventID
,coalesce(Reservations.ResCount,0)
from EventDates cross join Events -- one row for each event/date
left Outer Join Reservations -- join existing reservations
on Events.EventID=Reservations.EventID
and EventDates.SelDate = Reservations.EventDate
order by Events.EventID, EventDates.SelDate
See fiddle

SQL left outer join to find not in 3 tables

I'd like to get a count of items not in 3 tables. The third table is in another database and should only be for producer_ID 139.
Run as this I get 859 as a count:
SELECT count(item.item_ID) as itemcount
FROM item
LEFT OUTER JOIN item_Subject
ON (item.item_ID = item_Subject.item_ID)
LEFT OUTER JOIN item_Category
ON (item.item_ID = item_Category.item_ID)
LEFT OUTER JOIN DATABASE2.dbo.item_SuperCategory
ON (item.item_ID = DATABASE2.dbo.item_SuperCategory.item_ID
and DATABASE2.dbo.item_SuperCategory.Producer_ID = 139)
WHERE item_Category.item_ID IS NULL
and item_Subject.item_ID IS NULL
and DATABASE2.dbo.item_SuperCategory.item_ID IS NULL
But if I take out the DATABASE2.dbo.item_SuperCategory.Producer_ID = 139 and run I get only 23. I expected the number to be reduced, not increased. What is wrong?
This query counts items which have null itemID. The fact that you get 23 as opposed to 859 after removing the producer_id = 139 means that items with a producer_id of 139 account for 836 of your items in the DATABASE2.dbo.item_SuperCategory table.
Remember that you're searching for null values in a left-joined table, so to further filter that table alone in the join clause can only increase nulls.

Additional inner join modifying results of previous calculations

I am having issues with using the count() function in an sql plus query.. say if
SELECT B.ID COUNT(S.BRANCH_ID) FROM BRANCH B
INNER JOIN STAFF S ON S.BRANCH_ID = B.ID
GROUP BY B.ID;
from doing this I'll get the results
b.id count
1 6
2 6
3 6
4 7
5 6
which is fine.. However if I even add an extra inner join i'll get completely different and wrong results.. So if I put for example..
SELECT COUNT(S.BRANCH_ID) FROM BRANCH B
INNER JOIN STAFF S ON S.BRANCH_ID = B.ID
INNER JOIN TOOL_STOCK TS ON TS.BRANCH_ID = B.ID
GROUP BY B.ID;
Now the results I get will be...
b.id count
1 96
2 96
3 96
4 112
5 96
Why is this and how do I stop it? Cheers!
Try
SELECT B.ID, COUNT(DISTINCT S.STAFF_ID) FROM BRANCH B
INNER JOIN STAFF S ON S.BRANCH_ID = B.ID
INNER JOIN TOOL_STOCK TS ON TS.BRANCH_ID = B.ID
GROUP BY B.ID;
replacing S.STAFF_ID with the primary key field from the STAFF table.
Your problem is that the COUNT function returns the number of rows matching the GROUP BY clause after all rows have been joined and returned.
In your initial query you are finding the number of employees for each branch, In the second the number of employees is multiplied by the number of stock items.
When you add the second join, you are getting the counts for STAFF + TOOLS at each branch.
You will likely need to add a subquery if you want all the data returned, but only counts of one record type.
I think the key to your issue is, which are you actually trying to count?