How can I combine 2 group by conditions? I have records for each id for every hour in a day and I want to group information by first id and all records for that id in that day then second id and all records for that in the day.
My sample query is this:
SELECT
r.name
, r.network
, r.namestring
, i.name
, i.description
, r.rid
, i.id
, d.dtime
, d.ifInOctets
FROM router AS r
INNER JOIN interface AS i
ON r.rid = i.rid
INNER JOIN 1279080000_1_60 AS d
ON i.id = d.id
AND dtime BETWEEN 1279113600 AND 1279115400
WHERE r.network = "ITPN"
AND i.status = "active"
GROUP BY i.id AND d.dtime // each id with all its dtime
This always ends up giving me an aggregate value for that id.
Any idea what I could use??? I don't want to sum up all values.
Thank you,
To group by multiple expressions you should separate them with a comma, not AND:
GROUP BY i.id, d.dtime
You should also ensure that two records form the same day have the same value of dtime. It's not clear from your question whether this is or is not the case.
Related
I have this query with 2 LEFT JOINS each with a sub-query.
The sub-queries should select the row with the latest date PointsChangeDate__c for a specific campaign e.g: PointsTypeCode__c = '1'.
Problem is that it is choosing what appears to be just random dates.
If I run just one JOIN / sub-query, then the result is correct, but when I add the 2nd JOIN / sub-query, then the results are incorrect and it seems to be pulling random dates.
I suspect my issue is with the type of JOIN I am using, but I cannot see why, because if I LEFT JOIN, then I am including all results (a._ContactKey) pulled from the first query and carrying that all the way through.
SELECT
a._ContactKey ContactId,
a.Full_Name_1__c Full_Name,
a.MC_Phone__c Mobile,
a.POSCustomerNumber__c POS_Customer_Number,
a.POSCustomerStatus__c POSCustomerStatus,
'IL' Locale,
a.Mobile_1__c Mobile_for_text,
g.TotalPoints__c TotalPoints_SourceMethod_1,
g.ValidUntil__c ValidUntil_SourceMethod_1,
g.date_1 PointsChangeDate__c_1,
h.TotalPoints__c TotalPoints_SourceMethod_2,
h.ValidUntil__c ValidUntil_SourceMethod_2,
h.date_2 PointsChangeDate__c_2
FROM
Contact_Salesforce AS a
LEFT JOIN
(SELECT
Contact__c,
TotalPoints__c,
ValidUntil__c,
MAX(PointsChangeDate__c) date_1
FROM
Member_points__c_Salesforce
WHERE
PointsTypeCode__c = '1'
GROUP BY Contact__c , TotalPoints__c , ValidUntil__c, PointsChangeDate__c) AS g ON a._ContactKey = g.Contact__c
LEFT JOIN
(SELECT Contact__c,
TotalPoints__c,
ValidUntil__c,
MAX(PointsChangeDate__c) date_2
FROM
Member_points__c_Salesforce
WHERE
PointsTypeCode__c = '2'
GROUP BY Contact__c , TotalPoints__c , ValidUntil__c, PointsChangeDate__c) AS h ON h.Contact__c = g.Contact__c
LEFT JOIN
SMS_Unsubscribe AS c ON REPLACE(CONCAT('972',
RIGHT(RTRIM(LTRIM(a.Mobile_1__c)), 9)),
'-',
'') = c.Mobile
LEFT JOIN
Member_Segments__c_Salesforce AS b ON b.Contact__c = a._ContactKey
WHERE
a.Mobile_1__c IS NOT NULL
AND c.Mobile IS NULL
AND a.POSCustomerStatus__c = '0'
AND b.IsActive__c = 'true'
GROUP BY a._ContactKey , a.Full_Name_1__c , a.MC_Phone__c , a.POSCustomerNumber__c , a.POSCustomerStatus__c , Locale , a.Mobile_1__c , a.Mobile_1__c , b.SegmentTypeID__c, b.SegmentTypeDescription__c , b.ToDate__c , g.TotalPoints__c , g.ValidUntil__c, g.date_1
,h.TotalPoints__c , h.ValidUntil__c, h.date_2
I am trying to combine two SQL queries the first is
SELECT
EAC.Person.FirstName,
EAC.Person.Id,
EAC.Person.LastName,
EAC.Person.EmployeeId,
EAC.Person.IsDeleted,
Controller.Cards.SiteCode,
Controller.Cards.CardCode,
Controller.Cards.ActivationDate,
Controller.Cards.ExpirationDate,
Controller.Cards.Status,
EAC.[Group].Name
FROM
EAC.Person
INNER JOIN
Controller.Cards ON EAC.Person.Id = Controller.Cards.PersonId
INNER JOIN
EAC.GroupPersonMap ON EAC.Person.Id = EAC.GroupPersonMap.PersonId
INNER JOIN
EAC.[Group] ON EAC.GroupPersonMap.GroupId = EAC.[Group].Id
And the second one is
SELECT
IsActive, ActivationDateUTC, ExpirationDateUTC,
Sitecode + '-' + Cardcode AS Credential, 'Badge' AS Type,
CASE
WHEN isActive = 0
THEN 'InActive'
WHEN ActivationDateUTC > GetUTCDate()
THEN 'Pending'
WHEN ExpirationDAteUTC < GetUTCDate()
THEN 'Expired'
ELSE 'Active'
END AS Status
FROM
EAC.Credential
JOIN
EAC.WiegandCredential ON Credential.ID = WiegandCredential.CredentialId
WHERE
PersonID = '32'
Where I would like to run the second query for each user of the first query using EAC.Person.Id instead of the '32'.
I would like all the data to be returned in one Dataset so I can use it in Report Builder.
I have been fighting with this all day and am hoping one of you smart guys can give me a hand. Thanks in advance.
Based on your description in the comments, I understand that the connection between the two datasets is actually the PersonID field, which exists in both EAC.Credential and EAC.Person; however, in EAC.Credential, duplicate values exist for PersonID, and you want only the most recent one for each PersonID.
There are a few ways to do this, and it will depend on the number of rows returned, the indexes, etc., but I think maybe you're looking for something like this...?
SELECT
EAC.Person.FirstName
,EAC.Person.Id
,EAC.Person.LastName
,EAC.Person.EmployeeId
,EAC.Person.IsDeleted
,Controller.Cards.SiteCode
,Controller.Cards.CardCode
,Controller.Cards.ActivationDate
,Controller.Cards.ExpirationDate
,Controller.Cards.Status
,EAC.[Group].Name
,X.IsActive
,X.ActivationDateUTC
,X.ExpirationDateUTC
,X.Credential
,X.Type
,X.Status
FROM EAC.Person
INNER JOIN Controller.Cards
ON EAC.Person.Id = Controller.Cards.PersonId
INNER JOIN EAC.GroupPersonMap
ON EAC.Person.Id = EAC.GroupPersonMap.PersonId
INNER JOIN EAC.[Group]
ON EAC.GroupPersonMap.GroupId = EAC.[Group].Id
CROSS APPLY
(
SELECT TOP 1
IsActive
,ActivationDateUTC
,ExpirationDateUTC
,Sitecode + '-' + Cardcode AS Credential
,'Badge' AS Type
,'Status' =
CASE
WHEN isActive = 0
THEN 'InActive'
WHEN ActivationDateUTC > GETUTCDATE()
THEN 'Pending'
WHEN ExpirationDateUTC < GETUTCDATE()
THEN 'Expired'
ELSE 'Active'
END
FROM EAC.Credential
INNER JOIN EAC.WiegandCredential
ON EAC.Credential.ID = EAC.WiegandCredential.CredentialId
WHERE EAC.Credential.PersonID = EAC.Person.PersonID
ORDER BY EAC.Credential.ID DESC
) AS X
-- Optionally, you can also add conditions to return specific rows, i.e.:
-- WHERE EAC.Person.PersonID = 32
This option uses a CROSS APPLY, which means that every row of the first dataset will return additional values from the second dataset, based on the criteria that you described. In this CROSS APPLY, I'm joining the two datasets based on the fact that PersonID exists in both EAC.Person (in your first dataset) as well as in EAC.Credential. I then specify that I want only the TOP 1 row for each PersonID, with an ORDER BY specifying that we want the most recent (highest) value of ID for each PersonID.
The CROSS APPLY is aliased as "X", so in your original SELECT you now have several values prefixed with the X. alias, which just means that you're taking these fields from the second query and attaching them to your original results.
CROSS APPLY requires that a matching entry exists in both subsets of data, much like an INNER JOIN, so you'll want to check and make sure that the relevant values exist and are returned correctly.
I think this is pretty close to the direction you're trying to go. If not, let me know and I'll update the answer. Good luck!
Try like this;
select Query1.*, Query2.* from (
SELECT
EAC.Person.FirstName,
EAC.Person.Id as PersonId,
EAC.Person.LastName,
EAC.Person.EmployeeId,
EAC.Person.IsDeleted,
Controller.Cards.SiteCode,
Controller.Cards.CardCode,
Controller.Cards.ActivationDate,
Controller.Cards.ExpirationDate,
Controller.Cards.Status,
EAC.[Group].Name
FROM
EAC.Person
INNER JOIN
Controller.Cards ON EAC.Person.Id = Controller.Cards.PersonId
INNER JOIN
EAC.GroupPersonMap ON EAC.Person.Id = EAC.GroupPersonMap.PersonId
INNER JOIN
EAC.[Group] ON EAC.GroupPersonMap.GroupId = EAC.[Group].Id)
Query1 inner join (SELECT top 100
IsActive, ActivationDateUTC, ExpirationDateUTC,
Sitecode + '-' + Cardcode AS Credential, 'Badge' AS Type,
CASE
WHEN isActive = 0
THEN 'InActive'
WHEN ActivationDateUTC > GetUTCDate()
THEN 'Pending'
WHEN ExpirationDAteUTC < GetUTCDate()
THEN 'Expired'
ELSE 'Active'
END AS Status
FROM
EAC.Credential
JOIN
EAC.WiegandCredential ON Credential.ID = WiegandCredential.CredentialId
ORDER BY EAC.Credential.ID DESC) Query2 ON Query1.PersonId = Query2.PersonID
Just select two queries to join them like Query1 and Query2 by equaling PersonId data.
I am filtering the data of more than one table by sql select query and for that I am using left outer join in c#.net. So by excuting this query filter is not working properly.
For ex : I have data whose branchid is 1 and yearid is 1. So when excute the query it works fine i.e. it shows that data only whose branch and year id is 1.
other data whose branchid is 2 and yearid is 1. So when I am excuting the query according to this filter at that time it shows branchid is 1 and yearid is 1 and also branchid is 2 and yearid is 1.
means at second time it shows whole data of branch and yearid. So at that time filter is not working.
Here is my query
SELECT DISTINCT
Client.clientname AS ClientName ,
RetailInvoice.invoiceno AS InvoiceNo ,
RetailInvoice.pono AS PoNO ,
RetailInvoice.issuedate AS IssueDate ,
RetailInvoice.duedate AS DueDate ,
RetailInvoice.discount AS Discount ,
RetailInvoice.shipping AS Shipping ,
RetailInvoice.tax AS Tax ,
RetailInvoice.vat AS Vat ,
RetailInvoice.sese AS Sese ,
RetailInvoice.paymenttype AS PaymentType ,
RetailInvoice.chequeno AS Chequeno ,
RetailInvoice.totalamt AS TotalAmt ,
RetailInvoice.description AS Description ,
RetailInvoice.paymentpaid AS PaymentPaid ,
RetailInvoice.subtotal AS Subtotal ,
RetailInvoicePayment.productid AS ProductName ,
RetailInvoicePayment.uom AS Uom ,
RetailInvoicePayment.quantity AS Quantity ,
RetailInvoicePayment.price AS Price
FROM tbl_retailinvoice RetailInvoice
LEFT OUTER JOIN tbl_retailinvoicepayment RetailInvoicePayment
ON RetailInvoice.invoiceno = RetailInvoicePayment.invoiceno
LEFT OUTER JOIN tbl_clientdetail Client
ON RetailInvoice.clientid = Client.clientid
WHERE RetailInvoice.BranchID = 1
AND RetailInvoice.YearID = 1
AND RetailInvoice.invoiceno = 1;
In your query:
FROM tbl_retailinvoice RetailInvoice
LEFT OUTER JOIN tbl_retailinvoicepayment RetailInvoicePayment
ON RetailInvoice.invoiceno = RetailInvoicePayment.invoiceno
LEFT OUTER JOIN tbl_clientdetail Client
ON RetailInvoice.clientid = Client.clientid
WHERE RetailInvoice.BranchID = 1
AND RetailInvoice.YearID = 1
AND RetailInvoice.invoiceno = 1;
All three conditions in the WHERE clause are focused on the table RetailInvoice. You say that even if you change the where condition to this:
WHERE RetailInvoice.BranchID = 2
AND RetailInvoice.YearID = 1
AND RetailInvoice.invoiceno = 1;
..that it still shows you rows where RetailInvoice.BranchID = 1. Vaguely speaking, that shouldn't be possible, since your WHERE clause would specifically dictate that only rows with a BranchID of 2 be returned. I say "vaguely speaking" because I don't have a lot of information to go on here, but in principle what you're saying seems nonsensical.
Something in the description of the problem doesn't add up to me. This problem should not be related to the LEFT JOIN, since none of the WHERE conditions point to one of the tables included by LEFT JOIN. In other words, the problem appears to be elsewhere.
FYI, LEFT JOIN simply means "Show me the information from
RetalInvoice even if there are no matching rows in the
RetailInvoicePayment or Client tables."
As opposed to an INNER JOIN, which would only show you data where a matching row was present in all three tables.
I have written a query that returns the list of all customers that have ever made a purchase with the company I work for. The person for whom I am getting the data would like to know if a specific criteria is true for any of these orders.
select L.ParentLocation,
[Number of Orders] = count(distinct(T.Order))
from Table1 L
join Table2 T
on L.Location = T.Location
group by L.ParentLocation
However, the issue is complicated because I am already grouping by ParentLocation, and each ParentLocation has many normal Locations. So I am counting the number of unique orders at the location level, then grouping them by the ParentLocation.
I want to return 'TRUE' in the query if a field 'OrderDesc' contains "Toys" in ANY of the orders by ANY of the Locations owned by a ParentLocation. Is there a way to do this?
NOTE: Table2 contains the OrderDesc column.
Thanks for reading!
select
L.ParentLocation,
[Number of Orders] = count(distinct(T.Order)),
has_toys = max(case when t.OrderDesc like '%toys%' then 'TRUE' else '' end)
from Table1 L
inner join Table2 T
on L.Location = T.Location
group by
L.ParentLocation
I have 3 tables that are joined together with this query.
One of them brings me people names , another one brings me their points and the last one brings me date time.
I select the total people score.
Also, there is a column in the 3th tables that brings me the scores' transaction Date Time. My problem is that I want to write a TSQL query with this condition:
Select the transaction date where the people score is 12,000 or more.
In my idea I should use while loop but I do not know the syntax?
This is how I would do it-
SELECT cp.FirstName
, cp.LastName
, SUM(Points) as Score
FROM ClubProfile cp
RIGHT JOIN CardTransaction ct
ON cp.ClubProfileId = ct.ClubProfileId
INNER JOIN Your3rdTable as t3
ON cp.ClubProfileId = t3.ClubProfileId
WHERE CONVERT(VARCHAR, ct.[Date Column], 101) = #your_date_param
GROUP BY
cp.FirstName
, cp.LastName
HAVING SUM(Points) >=12000
Based on your post this should be close to what you need. You need to add that 3rd table and alter this statement accordingly.
SELECT cp.FirstName
, cp.LastName
, SUM(Points) as Score
FROM [fidilio].[dbo].[ClubProfile] cp
RIGHT JOIN (
CardTransaction ct
INNER JOIN CardTransactionLog ctl
ON cp.CardTransactionLogId = ctl.CardTransactionLogId
)
ON cp.ClubProfileId = ct.ClubProfileId
GROUP BY
cp.FirstName
, cp.LastName
HAVING SUM(Points) >=12000
AND ctl.TransactionTimeStamp = #SomeDateTimeVariable
The variable #SomeDateTimeVariable has to come from someplace what is your exact time-frame criteria