I need a query to get the Name of the Clients where there is no Client Contact record and if there is any Client Contact then they are ended. Please see below table structure.
Table : Client
Client ID Client Name
-------------------------
1 John
2 Sean
3 Johnson
Table : Client_Contact
Client Contact ID Client ID Start Date End Date
---------------------------------------------------------
1 1 1/1/1999 2/2/1999
2 1 1/2/1999 2/3/1999
3 1 1/3/1999 2/4/1999
4 2 1/2/2005 1/2/2007
5 2 1/3/2005 NULL
The query will return Johnson and Sean.
Johnson has no Client Contact , so it is coming up in the Query
John has Client Contact but all the Client Contact are ended , so it is coming up in the query
Sean has Client Contact but one of the record is not ended , so it is not coming up in the query.
Thanks in advance for the query.
Here's a query pattern that I use for queries like this that can give substantial performance gains compared to "left join" patterns, when the tables involved get really large:
select c.[Client Name]
from Client c
where not exists
(
select *
from Client_Contact cc
where c.[Client ID] = cc.[Client ID]
and cc.[End Date] is null
)
Try ..
select distinct cl.*
from Client cl
left outer join Client_Contact clcnt
on cl.[Client ID] = clcnt.[Client ID]
where (clcnt.[Client ID] IS NULL OR clcnt.[End Date] IS NULL)
I hope this query might work for you
select c.* from client c
left join (select max([Client Contact ID]) ClientContactID,[Client ID] from client_contact
group by [client id]) ce on c.[Client ID]=ce.[Client ID]
left join client_contact ce1 on ce.[Client Contact ID]=ce1.[Client Contact ID]
where ce.[Client ID] is null
or ce1.[End Date] is not null
Related
I have a table like below after several joins
username trandate positionname ChannelID
-------- ---- ------------ ---------
system 01/01/2019 1
anderson 06/04/2019 chief 1
williams 07/03/2019 chief 2
julie 15/02/2019 technician 48
julie 27/05/2019 chief technician 21
I want to count total number of transactions, sum of amount grouped by month, year and channel type.
there is a condition: if channelID is equals to "1", then query should exclude (1) transactions with has null value on "positionname" or (2) transactions with "system" username.
My code is something like this below:
select DISTINCT
DATEPART(YEAR,a.TranDate) as [year],
DATEPART(MONTH,a.TranDate) as [month],
count(*) as [transaction number],
sum(a.Amount) as [Total amount],
b.Name as [branch name],
c.ChannelName as [channel]
from transactions_main as a
left join branches as b WITH (NOLOCK) ON a.TranBranch=b.BranchId
left join Channels as c WITH (NOLOCK) ON a.ChannelId=c.ChannelId
left join Staff_Info as d WITH (NOLOCK) ON a.UserName=d.UserCode
where
a.TranDate>'20181231'
and b.name not in ('HQ')
and (a.ChannelId=1
and d.positionname is not null
and a.UserName not in ('SYSTEM', 'auto') )
group by b.Name, c.ChannelName,DATEPART(YEAR,a.TranDate), DATEPART(MONTH,a.TranDate)
order by b.Name, Year,month
In the end, of course, it didnt worked. I got the sum and count of transactions of only channelID=1's.
BONUS: You want to help another topic of mine? in which i also need help about indexing:
determining the staff's title when a certain transaction is done
here it is : link
use an OR operator
where
a.TranDate>'20181231'
and b.name not in ('HQ')
and (
(a.ChannelId=1
and d.positionname is not null
and a.UserName not in ('SYSTEM', 'auto') )
)
OR
a.ChannelId<>1
)
Using Microsoft SQL Server
I need to create a table that takes the User IDs from the temp table. Collects only those User IDs and then adds all of the Points for that individual user together.
Temp table which pulled all the most recent records for each User ID.
User ID | Points | Date Field
-----------------------------
1 1 10/31/2016
3 1 08/26/2016
Main
User ID | Points | Date Field | Other Field
--------------------------------------------
1 1 10/31/2016 N/A
1 2 10/25/2016 N/A
1 3 09/18/2016 N/A
2 1 08/17/2017 N/A
2 16 07/11/2017 N/A
3 1 08/27/2016 N/A
3 5 05/14/2016 N/A
So take temp table and match those User IDs to the main table. From that data you should only have collected those which match the record IDs in the temp table. From there the report will then be broken down to look like below. Which shows the most recent date, and a sum of all the points for that User ID.
User ID | Points | Date Field | Other Field
---------------------------------------------
1 6 10/31/2016 N/A
3 6 08/27/2016 N/A
I tried this SQL:
SELECT
a.[User ID], a.[Points], a.[Date Field], a.[Other Field1], a.[Other Field2], a.[Other Field3],
(CASE WHEN b.[User ID] = a.[User ID] THEN SUM(a.Points) END) AS [Total Points]
FROM
Main_Table a
INNER JOIN
#Temp b ON b.[User ID] = a.[User ID]
GROUP BY
a.[User ID], [Points], [Date Field], [Other Field1], [Other Field2], [Other Field3]
I get the total points column, but is not adding all the fields with identical User IDs together.
I just need to know where I am going wrong. I'm not the best with SQL and I'm still learning. Please understand I am trying my best to figure this out.
Thank you!
I imagine something like this is what you're looking for:
SELECT
b.[User ID]
, b.[Points]
, b.[Date Field]
, SUM(a.Points) [Total Points]
FROM
#Temp b
INNER JOIN Main_Table a ON b.[User ID] = a.[User ID]
GROUP BY
b.[User ID]
, b.[Points]
, b.[Date Field]
But then the question would be, which of the other fields from Main_Table do you want to keep?
I imagine possibly something like this:
SELECT
b.[User ID]
, b.[Points]
, b.[Date Field]
, m.[Other_Field] -- etc.
, SUM(a.Points) [Total Points]
FROM
#Temp b
INNER JOIN Main_Table m ON
b.[User ID] = m.[User ID]
AND b.[Date Field] = m.[Date Field]
INNER JOIN Main_Table a ON b.[User ID] = a.[User ID]
GROUP BY
b.[User ID]
, b.[Points]
, b.[Date Field]
, m.[Other_Field]
To get Sum, you have to group by fields that are non-changing. So User ID is the non-changing field you would want to SUM by. The group by is done to this non-aggregate field User ID. The problem with date and [Other Field] is that they are changing often. This defeats the group by. You have to query back to the original table to get the max date field if that's your intent. I'm not sure what [Other Field] are, but you have to take into account if they are different changing values.
SELECT dT.[User ID]
,dT.Points
,(SELECT MAX([Date Field])
FROM #main M2
WHERE M2.[User ID] = dT.[User ID]) AS [Date Field]
FROM (
SELECT M.[User ID]
,SUM(M.Points) AS Points
FROM #main M
WHERE [User ID] IN (SELECT [User ID] FROM #temp)
GROUP BY M.[User ID]
) AS dT
Creates output:
User ID Points Date Field
1 6 2016-10-31
3 6 2016-08-27
I assume this should help
--======================= CREATE TEMP TABLE==============================
CREATE TABLE #TEMP ([USER ID] INT,
POINTS INT,
[DATE FIELD] DATE)
--======================= VALUES ON THE TABLE ===============================
INSERT INTO #TEMP VALUES ( 1 ,1,'10-31-2016')
INSERT INTO #TEMP VALUES (3,1,'08-26-2016')
--======================== CREATE MAIN TABLE ============================
CREATE TABLE #MAIN ([USER ID] INT,
POINTS INT,
[DATE FIELD] DATE,
[OTHER FIELD] NVARCHAR(50))
--======================= VALUES ON MAIN TABLE===================
INSERT INTO #MAIN VALUES ( 1,1,'10-31-2016','N/A')
INSERT INTO #MAIN VALUES ( 1,2,'10-25-2016','N/A')
INSERT INTO #MAIN VALUES ( 1,3,'09-18-2016','N/A')
INSERT INTO #MAIN VALUES ( 2,1,'08-17-2017','N/A')
INSERT INTO #MAIN VALUES ( 2,16,'07-11-2017','N/A')
INSERT INTO #MAIN VALUES ( 3,1,'08-27-2016','N/A')
INSERT INTO #MAIN VALUES ( 3,5,'05-14-2016','N/A')
--=====GETTING SUM OF YOUR POINTS=====
SELECT T2.[USER ID],
SUM(T1.[POINTS]) AS [TOTAL POINT],
T2.[DATE FIELD],
T1.[OTHER FIELD]
FROM #MAIN AS T1
RIGHT JOIN #TEMP AS T2
ON T1.[USER ID] = T2.[USER ID]
GROUP BY T2.[USER ID],
T2.[DATE FIELD],
T1.[OTHER FIELD]
DROP TABLE #TEMP
DROP TABLE #MAIN
I am using microsoft access and I have a total of 3 tables: Credits, Orders, and Books which are shown below. I need to create an update query that updates the existing Number of Credits for each student based on the books that they have ordered and the corresponding amount of credits for each book.
For instance, student B-17 starts with 24 credits but after the update query it should change the student's credits to 32.
Credits Table
Student ID Number of Credits
B-17 24
F-59 30
Orders Table
Student ID Book ID
B-17 101
B-17 102
F-59 101
F-59 105
Books Table
Book ID Book Title Credits
101 English I 3
102 Accounting 5
105 Calculus 5
This is what I am trying but I keep getting a syntax error in Access.
UPDATE Credits c
SET [Number of Credits] = [Number of Credits] + (SELECT SUM(Credits)
FROM Orders o, Books b ON
o.[Book ID] = b.[Book ID] WHERE
c.[Student ID] = o.[Student ID])
WHERE c.[Student ID] = o.[Student ID];
You can try to use TEMP table for storing your data from the 2nd and 3rd tables; Do like this: 1) create another 4th table (i.e. Temp) with two columns: Student ID and Credits; 2) run this script:
SELECT o.[Student ID], sum (b.Credits) as Credits INTO Temp
FROM books b INNNER JOIN orders o
on b.[Book ID] = o.[Book ID]
GROUP BY o.[Student ID];
3) Start to Update:
UPDATE Credits c, Temp t set c.[Number of Credits] = c.[Number of Credits] + t.Credits
WHERE c.[Student ID] = t.[Student ID];
4) Save and Finished!
Useful: 1) "Operation must use an updateable query" error in MS Access;
2) MS Access database (2010) how to create temporary table/procedure/view from Query Designer
I'm trying to perform a query (using Access 2010) on the following tables:
Contact | Facility_Contact | Facility | Bank
| | |
ID | (fk) Contact_ID | ID | ID
CName | (fk) Facility_ID | FName | BName
| | BNumber | BNumber
I would like the final result to display:
CName | FName | BName
Here is the query:
SELECT
HUD.[HOLDER NAME], Facility.PROVNAME, Contact.LAST_NAME
FROM
Facility INNER JOIN Bank ON Facility.[BNumber] = Bank.[BNumber]) INNER JOIN
(Contact INNER JOIN Facility_Contact ON Contact.[ID] = Facility_Contact.[Contact_ID]) ON Facility.[ID] = Facility_Contact.[Facility_ID];
This doesn't produce any results.
The problem comes up when I add the "Bank" table. Queries from Contact to Facility work, as do queries from Facility to Bank. However I'm having difficulty producing results when trying to link from Contact to Bank.
Maybe a Where-like clause somewhere? But now I'm speaking of things that I'm not too familiar with ;)
Thank you all!
FROM
Facility INNER JOIN Bank ON Facility.[BNumber] = HUD.[BNumber])
You close a paranthetical but never open it. Although that would result in an error, so I assume that is a typo.
Facility INNER JOIN Bank ON Facility.[BNumber] = HUD.[BNumber]
You are joining Facility with Bank but then in your ON clause you state that Facility.[BNumber] = HUD.[BNumber] Where did HUD come from? This is not good.
Facility INNER JOIN Bank ON Facility.[BNumber] = HUD.[BNumber]) INNER JOIN (Contact INNER JOIN Facility_Contact ON Contact.[ID] = Facility_Contact.[Contact_ID]) ON Facility.[ID] = Facility_Contact.[Facility_ID];
Your schema appears to be Facility->Bank; Facility->Facility_contact->Contact. Consider rewriting to reflect this (This is just for readability):
FROM
Facility
INNER JOIN Bank ON Facility.[BNumber] = Bank.[BNumber]
INNER JOIN Facility_Contact ON Facility.[ID] = Facility_Contact.[Facility_ID]
INNER JOIN Contact ON Facility_Contact.[Contact_ID] = Contact.[ID]
Now to get records returned all of those joins need contain data. There needs to be a matching BNUMBER in your Bank table for each BNumber in Facility table. There needs to be a matching facility_id in your Facility_Contact table for each ID in your Facility. There needs to be a matching ID in your Contact table for each Contact_ID in your Facility_Contact table. If any of these links are missing you will get 0 records. If you want to show Facilties and Bank Names regardless if they have a Facility Contact then consider using a LEFT JOIN instead:
FROM
Facility
INNER JOIN Bank ON Facility.[BNumber] = Bank.[BNumber]
LEFT JOIN Facility_Contact ON Facility.[ID] = Facility_Contact.[Facility_ID]
LEFT JOIN Contact ON Contact.[ID] = Facility_Contact.[Contact_ID]
This won't drop results just because you don't have a contact at the facility yet. Or that contact hasn't been set up in the Contact table.
I have a SQL table consists of id, name, email,.... I have another SQL table that has id, email, emailstatus but these 2 id are different they are not related. The only thing that is common between these 2 tables are emails.
I would like to join these 2 tables bring all the info from table1 and if the email address from table 1 and table 2 are same and emailstatus is 'Bounced'. But the query that I am writing gives me more record than I expected because there are multiple rows in tbl_webhook(second table) for each row in Applicant(first table) .I want to know if applicant has EVER had an email bounce.
Query without join shows 23000 record but after join shows 42000 record that is because of duplicate how I can keep same 23000 record only add info from second table?
This is my query:
SELECT
A.[Id]
,A.[Application]
,A.[Loan]
,A.[Firstname]
,A.[Lastname]
,A.[Email],
,H.[Email], H.[EmailStatus] as BouncedEmail
FROM Applicant A (NOLOCK)
left outer join [tbl_Webhook] [H] (NOLOCK)
on A.Email = H.Email
and H.[event]='bounced'
this is sample of desired data:
id email name emailFromTable2 emailstatus
1 test2#yahoo.com lili test2#yahoo.com bounced
2 tesere#yahoo.com mike Null Null
3 tedfd2#yahoo.com nik tedfd2#yahoo.com bounced
4 tdfdft2#yahoo.com sam Null Null
5 tedft2#yahoo.com james tedft2#yahoo.com bounced
6 tedft2#yahoo.com San Null
Use a nested select for this type of query. I would write this as:
select id, application, load, firstname, lastname, email,
(case when BouncedEmail is not null then email end) as EmailFromTable2,
BouncedEmail
from (SELECT A.[Id], A.[Application], A.[Loan], A.[Firstname], A.[Lastname], A.[Email],
(case when exists (select 1
from tbl_WebHook h
where A.Email = H.Email and H.[event] = 'bounced'
)
then 'bounced
end) as BouncedEmail
FROM Applicant A (NOLOCK)
) a
You can also do this with cross apply, but because you only really need one column, a correlated subquery also works.
;WITH DistinctEmails
AS
(
SELECT * , rn = ROW_NUMBER() OVER (PARTITION BY [Email] ORDER BY [Email])
FROM [tbl_Webhook]
)
SELECT
A.[Id]
,A.[Application]
,A.[Loan]
,A.[Firstname]
,A.[Lastname]
,A.[Email],
,H.[Email], H.[EmailStatus] as BouncedEmail
FROM Applicant A (NOLOCK) left outer join DistinctEmails [H] (NOLOCK)
on A.Email = H.Email
WHERE H.rn = 1
and H.[event]='bounced'
i believe query below should be enough to select distinct bounced email for you, cheer :)
SELECT
A.[Id]
,A.[Application]
,A.[Loan]
,A.[Firstname]
,A.[Lastname]
,A.[Email],
,H.[Email], H.[EmailStatus] as BouncedEmail
FROM Applicant A (NOLOCK)
Inner join [tbl_Webhook] [H] (NOLOCK)
on A.Email = H.Email
and H.[EmailStatus]='bounced'
basically i just change the joining to inner join and change the 2nd table condition from event to emailstatus, if u can provide your table structure and sample data i believe i can help you up :)