Sqlserver query to retrieve from child table - sql-server-2017

I have the following example table structure. Want to retrieve customer who didnt have notificationtypeid = 2 ie who have never been sent a reminder email.
Can anyone help me how to write the sql query for this?
CustomerNotification:
-------------------
CustomerId Notificationtypeid
8201 1
8201 2
8202 1
8203 1
10209 1
Customer:
--------
CustomerId
8201
8202
8203
10209
NotificationType:
----------------
Notificationtypeid Name
1 Invite email
2 Reminder
i tried the following but not working as i am sure this not how it should be written :
select cd.customerId
tn.notificationtypeid from Customer cd
inner join CustomerNotification tn
on cd.customerid= tn.customerid
where cd.customerid not in( select customrid from customnotification where notificationtypeid=2
)
order by cd.customerid
Expected Result:
CustomerId Notificationtypeid
8202 1
8203 1
10209 1
But using my query i get:
CustomerId Notificationtypeid
8201 1 <-- I dont want this in result
8202 1
8203 1
10209 1

select cd.customerId
tn.notificationtypeid from Customer cd
inner join CustomerNotification tn
on cd.customerid= tn.customerid
where cd.customerid not in( select customrid from customnotification where notificationtypeid=2)
This query solved my issue. Let me know if there is better way.

You can try this SQL Server query to get desired output:-
select CustomerId, Notificationtypeid from CustomerNotification
where Notificationtypeid =1

Related

Count values separately until certain amount of duplicates SQL

I need a Statement that selects all patients and the amount of their appointments and when there are 3 or more appointments that are taking place on the same date they should be counted as one appointment
That is what my Statement looks so far
SELECT PATSuchname, Count(DISTINCT AKTDATUM) AS AKTAnz
FROM tblAktivitaeten
LEFT OUTER JOIN tblPatienten ON (tblPatienten.PATID=tblAktivitaeten.PATID)
WHERE (AKTDeleted<>'J' OR AKTDeleted IS Null)
GROUP BY PATSuchname
ORDER BY AKTAnz DESC
The result should look like this
PATSuchname Appointments
----------------------------------------
Joey Patner 13
Billy Jean 15
Example Name 13
As you can see Joey Patner has 13 Appointments, in the real table though he has 15 appointments but three of them have the same Date and because of that they are only counted as 1
So how can i write a Statement that does exactly that?
(I am new to Stack Overflow, sorry if the format I use is wrong and tell me if it is.
In the table it looks like this.
tblPatienten
----------
PATSuchname PATID
------------------------
Joey Patner 1
Billy Jean 2
Example Name 3
tblAktivitaeten
----------
AKTDatum PATID AKTID
-----------------------------------------
08.02.2021 1 1000 ----
08.02.2021 1 1001 ---- So these 3 should counted as 1
08.02.2021 1 1002 ----
09.05.2021 1 1003
09.07.2021 2 1004 -- these 2 shouldn't be counted as 1
09.07.2021 2 1005 --
Two GROUP BY should do it:
SELECT
x.PATID, PATSuchname, SUM(ApptCount)
FROM (
SELECT
PATID, AKTDatum, CASE WHEN COUNT(*) < 3 THEN COUNT(*) ELSE 1 END AS ApptCount
FROM tblAktivitaeten
GROUP BY
PATID, AKTDatum
) AS x
LEFT JOIN tblPatienten ON tblPatienten.PATID = x.PATID
GROUP BY
x.PATID, PATSuchname

Eliminate database rows based on mod dates

I have an issue grabbing data from two tables base on a single field in one of the tables The field does not exist in both tables.
Example:
Table 1 (call it invoices):
invoice email customer_name original_bill invoice_status
1 a#g.com bob 5.00 P
2 a#g.com harry 23.00 P
3 a#g.com sally 4.00 P
4 b#g.com loretta 14.00 P
5 b#g.com hamish 74.00 P
Table 2 (customer invoice edits):
invoice email date_last_modified_timestamp mod_status mod_amount
1 a#g.com 2019-05-01 A 3.00
1 a#g.com 2019-04-01 D
3 b#g.com 2019-10-25 A
What I want
a list of all invioces and their mods but I only wish each invoice to appear once in the list. based on the latest date in Table two.
example:
invoice email customer_name original_bill invoice_status date_last_modified_timestamp mod_status mod_amount
1 a#g.com bob 5.00 P 2019-05-01 A 3.00
2 a#g.com harry 23.00 P
3 a#g.com sally 4.00 P 2019-10-25 A
4 b#g.com loretta 14.00 P
5 b#g.com hamish 74.00 P
How im pulling it now:
select invoice, email, customer_name, original bill, invoice status, max(date_last_modified_timestamp), mod status, mod_amount
from table one
left join on table1.invoice = table 2.invoice
group by
invoice, email, customer_name, original bill, invoice status, max(date_last_modified_timestamp), mod status, mod_amount
I've tried a gazzillion variation to no avail.
What i get
i do get accurate results, but those results inclues a duplicate row containing each invoice that has been modified. I only want one invoice per row. I want the one that's been modified last. Is this even possible? What am I doing wrong?
You can join and use a correlated subquery for filtering:
select i.*, e.*
from invoices i
inner join customer_invoice_edits e
on e.invoice = i.invoice
and e.date_last_modified_timestamp = (
select max(date_last_modified_timestamp)
from customer_invoice_edits e1
where e1.invoice = e.invoice
)
This will give you one record per row in the invoices table that has a match in customer_invoice_edits, along with the latest corresponding record in customer_invoice_edits.
If some invoices have no corresponding record in the dependant table, they will not appear in the resultset. If you do want to see them, then you can use a left join instead.
Is this what you want?
select
invoice,
email
from (
select
invoice,
email,
mod_status,
mod_amount,
date_last_modified_timestamp,
row_number() over (
partition by invoice, email
order by date_last_modified_timestamp desc
) rn
from table2
)
where rn=1
I'm pretty sure you want this field-by-field. Here is an example:
select i.invoice,
nz( (select top (1)
from invoice_edits as ie
where ie.invoice = i.invoice and ie.email is not null
), i.email
) as email,
nz( (select top (1)
from invoice_edits as ie
where ie.invoice = i.invoice and ie.mod_amount is not null
), i.original_bill
) as original_bill,
. . .
from invoices as i;

Getting total amount of orders using sql query

Hi lets say i have the following tow tables
first table is Orders which consist of following columns
Order_ID OrderDate
1 2016-01-20
2 2016-01-21
and the second table is OrderDetails which consist of following columns
Order_ID ProductID UnitPrice Quantity
1 1 5.00 1
1 3 20.00 3
2 2 10.00 2
How can i get the following out put
Order_ID OrderDate OrderTotalamount
1 2016-01-20 65.00
2 2016-01-21 20.00
Would you mind trying something like this out?
SELECT ORD.Order_ID, ORD.OrderDate, SUM(ORDD.UnitPrice * ORDD.Quanity) AS OrderTotalAmount
FROM Orders ORD
INNER JOIN OrderDetails ORDD
ON ORDD.Order_ID = ORD.Order_ID
GROUP BY ORD.Order_ID, ORD.OrderDate
You can try this
SELECT a.Order_ID, a.OrderDate, SUM(Quantity*UnitPrice) as OrderTotalamout
FROM Orders a JOIN OrderDetains ON (a.Order_ID = OrderDetails.Order_ID)
GROUP BY 1, 2;
I hope it works fine for you.
YOU CAN USE
SELECT TABLE1.Order_ID, TABLE1.OrderDate, SUM(TABLE2.Quantity*TABLE2.UnitPrice) as TotalPrice
FROM TABLE1 JOIN TABLE2 WHERE(TABLE1.Order_ID = TABLE2.Order_ID);

Concatenating data from one row into the results from another

I have a SQL Server database of orders I'm struggling with. For a normal order a single table provides the following results:
Orders:
ID Customer Shipdate Order ID
-----------------------------------------------------------------
1 Tom 2015-01-01 100
2 Bob 2014-03-20 200
At some point they needed orders that were placed by more than one customer. So they created a row for each customer and split the record over multiple rows.
Orders:
ID Customer Shipdate Order ID
-----------------------------------------------------------------
1 Tom 2015-01-01 100
2 Bob 2014-03-20 200
3 John
4 Dan
5 2014-05-10 300
So there is another table I can join on to make sense of this which relates the three rows which are actually one order.
Joint.Orders:
ID Related ID
-----------------------------------------------------------------
5 3
5 4
I'm a little new to SQL and while I can join on the other table and filter to only get the data relating to Order ID 300, but what I'd really like is to concatenate the customers, but after searching for a while I can't see how to do this. What'd I'd really like to achieve is this as an output:
ID Customer Shipdate Order ID
----------------------------------------------------------------
1 Tom 2015-01-01 100
2 Bob 2014-03-20 200
5 John, Dan 2014-05-10 300
You should consider changing the schema first. The below query might help you get a feel of how it can be done with your current design.
Select * From Orders Where IsNull(Customer, '') <> ''
Union All
Select ID,
Customer = (Select Customer + ',' From Orders OI Where OI.ID (Select RelatedID from JointOrders JO Where JO.ID = O.ID)
,ShipDate, OrderID
From Orders O Where IsNull(O.Customer, '') = ''

select result from three tables using sql

I want to get a result from three tables. i dont how to write the sql query. Please help me.
"I want to display Name,Username and Product_Name where Id=007"
table "register"
Name Username Id
Arj arjun 007
xyz abcd 008
abcd asdf 007
table "products"
Product_Id Product_Name Price
101 Clothes 200
102 Games 100
table "purchase" //products.Product_Id=purchase.Item
Username item Id
arjun 102 007
abcd 101 008
asdf 102 007
Try this query :
SELECT a.Name,a.Username,c.Product_Name
FROM register as a
JOIN purchase as b on a.Username=b.Username
JOIN products as c on b.item=c.Product_Id
It should work like this. To read more on SQL Joins try : http://www.w3schools.com/sql/sql_join.asp
Enjoy!
That should be like this
SELECT * FROM
register r
JOIN purchase p on p.username = r.username
JOIN products pr on pr.product_id = p.item
you can revise this basic code to include specific columns and add where and order clause.
SELECT Username, Id, Product_Name
FROM register
INNER JOIN purchase ON purchase.Id = register.Id
INNER JOIN products ON purchase.Item = products.Product_Id
WHERE Id = '007'
As a side note: you shouldn't save the Username in the purchase table too.