Need help with the SQL Subquery - sql-server

I want to count the total number of order detail rows over all orders a customer has ever had.
This is my query
SELECT SUM(
(SELECT count(*)
FROM dbo.Order_Details
WHERE dbo.Order_Details.OrderID = dbo.Orders.OrderID))
FROM dbo.Orders
WHERE dbo.Orders.CustomerID = "123"
SQL Server is giving me an error "Cannot perform an aggregate function on an expression containing an aggregate or a subquery."
Any help with this would be appreciated.

SELECT COUNT(*)
FROM Orders
INNER JOIN Order_Details ON Orders.OrderID = Order_Details.OrderID
WHERE Orders.CustomerID = "123"

Shouldn't it just be:
SELECT count(*) FROM dbo.Order_Details, dbo.Orders
WHERE dbo.Order_Details.OrderID = dbo.Orders.OrderID
AND dbo.Orders.CustomerID = "123"

You don't need the sum() since the count(*) is already going to give you the total.
SELECT (SELECT count(*)
FROM dbo.Order_Details
WHERE dbo.Order_Details.OrderID = dbo.Orders.OrderID)
FROM dbo.Orders
WHERE dbo.Orders.CustomerID = "123"

The Count(*) is doing the summation for you. Just remove the SUM aggregate from your expression.

I should think something like the following should do what you want:
select count(1) from dbo.order_details d
join dbo.orders o on d.OrderId=o.OrderId
where dbo.orders.CustomerID="123"

The following assumes you have a column in the Order_Details table called OrderDetailID. If not, just substitute for the unique identifier for the order detail record.
SELECT COUNT(DISTINCT OD.OrderDetailID)
FROM Orders O
LEFT JOIN Order_Details OD on (OD.OrderId = O.OrderId)
WHERE O.CustomerID = "123"

Related

SQL Query Group by Count and Left Join Tables

i need your help! I got some simple SQL skills, but this query kills me...
My Tables
Now i want the TOP5 WorkTimes on the Equipment (What Equipment got the longest WorkTime).
I want this OUTPUT:
MY Query:
SELECT
Equipment, EquipmentName, count(Equipment) as Count
FROM
Operations o
LEFT JOIN Orders ord ON ord.Id = o.[Order]
LEFT OUTER JOIN Equipments e ON ord.Equipment = e.EquipmentNumber
GROUP BY
Equipment, EquipmentName
ORDER BY Count DESC;
Another Question is how i can show o.Worktime?
i got an error with GroupBy...
please help me Thanks!
You can try this query:
select equip_nr,
(select equipmentname from table_equipments where equipmentnr = [to].equip_nr) equip_name,
sum(timeInMins) / 60.0 Worktime
from (
select (select equipmentnr from table_orders where id = [to].[order]) equip_nr,
case when workunittime = 'RH' then worktime * 60 else worktime end timeInMins
from table_operations [to]
where exists(select 1 from table_orders
where [to].[order] = id
and location = '152')
and [start] >= '2018-07-01 00:00:00.000' and [start] < '2018-08-01 00:00:00.000'
) [to] group by equip_nr
By the way, LEFT JOIN is equivalent to LEFT OUTER JOIN.
Just use SUM(worktime) as aggregate function, instead of COUNT(Equipment)
SELECT
e.[ID_Equipment]
, Name
, SUM( IIF(o.WorkUnitTime='MIN', worktime/60.0, worktime) ) as WorktimeMIN
FROM
Operations o
LEFT JOIN Orders ord ON ord.ID_Order = o.ID_Order
LEFT OUTER JOIN Equipment e ON ord.ID_Equipment = e.ID_Equipment
GROUP BY
e.[ID_Equipment]
, Name
ORDER BY
WorktimeMIN DESC
See SQL Fiddle here: http://sqlfiddle.com/#!18/5b5ed/11

Distinct columns after "ORDER BY" in SQL server 2014

I want to distinct columns after ORDER BY points.pPoint.
this is points table diagram:
I want something as following image on the right side but getting result as the left side:
and this is my code:
SELECT TOP(6) MedicalExpertise.meid
FROM physician INNER JOIN
MedicalExpertise ON physician.meid = MedicalExpertise.meid INNER JOIN
points ON physician.phId = points.phID
ORDER BY points.pPoint DESC
Perhaps something like this?
SELECT DISTINCT meid
FROM ( SELECT TOP ( 6 ) MedicalExpertise.meid
FROM physician
INNER JOIN MedicalExpertise ON physician.meid = MedicalExpertise.meid
INNER JOIN points ON physician.phId = points.phID
ORDER BY points.pPoint DESC ) d
ORDER BY 1 DESC;
Simply use distinct keyword,
Ex:
SELECT DISTINCT column1, column2, ...
FROM table_name;
Can you edit the original question what you really want? Does it have to be grouped by any column before getting distinct? Please update the question.

Cannot use a derived table in WHERE subquery

Why can't I use D in the WHERE subquery?
SELECT *
FROM dbo.Orders AS D
WHERE (SELECT COUNT(*)
FROM D) = 11;
That's simply not a valid syntax... Even if it was, you'd get no results unless there were exactly 11 rows in your Orders table.
I'm guessing that you're looking for something like the following...
WITH
cte_OrderCount AS (
SELECT
*,
OrderCount = COUNT(*) OVER (PARTITION BY o.CustomerID)
FROM
dbo.Orders o
)
SELECT
*
FROM
cte_OrderCount oc
WHERE
oc.OrderCount = 11;
Not sure exactly what you are trying to do, so I'm guessing. But this returns all rows of the table if it has 11 rows:
select * from dbo.Orders where exists(select 1 from dbo.Orders having COUNT(*) = 11)
Or maybe you were after something like this:
If you need to "join" with the count table, you could use APPLY. e.g.:
select c.*, o.* from
(select COUNT(*) as cc from dbo.Orders) c outer apply
(select * from dbo.Orders) o
WHERE c.cc = 11
The SELECT COUNT(*) line above will always return 1 row. The "c" derived table is then outer applied with the orders table. Then you can use "c" and "o" in the WHERE clause etc.

Using sub-queries and filter in WHERE clause while joining tables

SELECT DISTINCT(t1.Ticker),t2.SecurityID,t2.ClosePrice,t2.QuoteDateTime FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2
ON t2.SecurityID =t1.SecurityID
WHERE t2.QuoteDateTime IN (SELECT max(QuoteDateTime) FROM [Hub].[SecurityMaster].[SecurityPrices]) AND t1.SecurityTypeName = 'REIT'
I get an output with no data. The subquery doesn't run along with the other filter in the WHERE clause. I am not sure what I am doing wrong. Can somebody please help!
If you are trying to get the lastest row from SecurityPrices for each Ticker, one option is to use cross apply():
select --distinct /* distinct not needed if `Ticker` is unique on `smd`
smd.Ticker
, sp.SecurityID
, sp.ClosePrice
, sp.QuoteDateTime
from [Hub].[SecurityMaster].[SecurityMasterDetails] as smd
cross apply (
select top 1
i.SecurityID
, i.ClosePrice
, i.QuoteDateTime
from [Hub].[SecurityMaster].[SecurityPrices] i
where i.SecurityID = smd.SecurityID
order by i.QuoteDateTime desc
) as sp
where SecurityTypeName = 'REIT' /* which table does this column belong to? */
I think your query would be
SELECT DISTINCT TOP 1 WITH TIES
t1.Ticker,
t2.SecurityID,
t2.ClosePrice,
t2.QuoteDateTime
FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2 ON t2.SecurityID =t1.SecurityID
WHERE SecurityTypeName = 'REIT'
ORDER BY t2.QuoteDateTime DESC
You aren't getting results because the max(QuoteDateTime) record doesn't have SecurityTypeName = 'REIT'. I think you want the max(QuoteDateTime) for this SecurityTypeName, so this can be done with an INNER JOIN.
SELECT DISTINCT
(t1.Ticker),
t2.SecurityID,
t2.ClosePrice,
t2.QuoteDateTime
FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2
ON t2.SecurityID =t1.SecurityID
INNER JOIN
(SELECT max(QuoteDateTime) DT FROM [Hub].[SecurityMaster].[SecurityPrices]) P on P.DT = t2.QuoteDateTime
WHERE SecurityTypeName = 'REIT'
EDIT
Your data doesn't have what you think it does, I suspect. Here is how you can check...
--Find the SecurityID that matches the max date
SELECT
SecurityID ,
max(QuoteDateTime) DT
FROM [Hub].[SecurityMaster].[SecurityPrices]
GROUP BY SecurityID
--I'm betting this ID isn't in your SecurityMasterDetails where the Type is REIT
SELECT DISTINCT
SecurityID
FROM SecurityMasterDetails
WHERE SecurityTypeName = 'REIT'
Since the SecurityID returned in the first query isn't in the second query result set, you are going to get NULL results.

Performing a conditional join in SQL Server

I have a SQL Server database. My database has two tables:
Customer Order
-------- -----
ID (int) ID (int)
Name CustomerID (int)
EmailAddress
When I query these tables, I might have a orderID. If I have an order ID, I want to return the customer associated with it. If I do NOT have an order ID, or if it equals 0, I want to return all of the customers. In an attempt to do this, I've written the following query:
SELECT
o.[ID]
FROM
[Order] o
WHERE
o.[ID]=#orderID
This query returns all orders with OrderID. However, I'm not sure how to do my conditional query. Is that even possible in SQL Server? If so, how?
For what you want you could use a case statement with Conduit's answer. Basically
CASE
WHEN #orderid = 0 OR #orderid IS NULL
SELECT * from Customer
ELSE
select c.*
from Customer c
inner join order o
on c.ID = o.CustomerID
where o.orderID = #orderID
END;
It may not be exact, I am not on a box with Sql Server installed.
I can think of a few ways to do this:
SELECT *
FROM Customer
WHERE CustomerID = coalsece( (select TOP 1 customerID from Orders WHERE OrderId= #OrderID), CustomerID)
.
With CustomerOrders As (
SELECT CustomerID, ID as OrderID
FROM Orders
WHERE OrderID = #OrderID
)
SELECT DISTINCT c.*
FROM Customer c
INNER JOIN CustomerOrders co ON c.ID = coalesce(co.CustomerID, c.ID)
You can achieve it using COALESCE in sql server -
SELECT c.*
FROM customer c
WHERE c.Id IN (
SELECT o.[CustomerID]
FROM [Order] o
WHERE o.[ID] = COALESCE(#orderID, o.[ID])
)

Resources