how to optimize the inner query? - sql-server

SELECT mark.student_id,
.
.
.
MAX(mark.SAVE_TIME) AS SAVE_TIME,
(SELECT tamil FROM mark WHERE SAVE_TIME = (MAX(mark.SAVE_TIME))) AS tamilmark,
(SELECT english FROM mark WHERE SAVE_TIME = (MAX(mark.SAVE_TIME))) AS englishmark
FROM
(.......
)
Above query will return the my expected data. but the problem is two times I'm fetching the data from same table. How can i achieve with single select statement?

Here is one way that could be rewritten:
SELECT MySubTable.*, mark.tamil, mark.english
(
SELECT student_id,
MAX(mark.SAVE_TIME) AS SAVE_TIME
FROM Table
GROUP BY student_id
) MySubTable
INNER JOIN mark
ON mark.SAVE_TIME = MySubTable.SAVE_TIME

You can use one select statement to get all values, but you also will get NULLs (in my example I gave them 'n/a' value). To get rid of them you will have to select this subquery:
SELECT *
FROM (
SELECT DISTINCT mark.student_id,
MAX(MARK.SAVE_TIME) OVER() AS SAVE_TIME,
CASE WHEN SAVE_TIME = (MAX(mark.SAVE_TIME) OVER()) THEN tamil ELSE 'n/a' END AS tamilmark,
CASE WHEN SAVE_TIME = (MAX(mark.SAVE_TIME) OVER()) THEN english ELSE 'n/a' END AS englishmark
FROM MARK
) AS t
WHERE tamilmark != 'n/a'

Related

Display of online users on the system

I don't know exactly where I'm wrong, but I need a list of all the workers who are currently at work (for the current day), this is my sql query:
SELECT
zp.ID,
zp.USER_ID,
zp.Arrive,
zp.Deppart,
zp.DATUM
FROM time_recording as zp
INNER JOIN personal AS a on zp.USER_ID, = zp.USER_ID,
WHERE zp.Arrive IS NOT NULL
AND zp.Deppart IS NULL
AND zp.DATUM = convert(date, getdate())
ORDER BY zp.ID DESC
this is what the data looks like with my query:
For me the question is, how can I correct my query so that I only get the last Arrive time for the current day for each user?
In this case to get only these values:
Try this below script using ROW_NUMBER as below-
SELECT * FROM
(
SELECT zp.ID, zp.USER_ID, zp.Arrive, zp.Deppart, zp.DATUM,
ROW_NMBER() OVER(PARTITION BY zp.User_id ORDER BY zp.Arrive DESC) RN
FROM time_recording as zp
INNER JOIN personal AS a
on zp.USER_ID = zp.USER_ID
-- You need to adjust above join relation as both goes to same table
-- In addition, as you are selecting nothing from table personal, you can drop the total JOIN part
WHERE zp.Arrive IS NOT NULL
AND zp.Deppart IS NULL
AND zp.DATUM = convert(date, getdate())
)A
WHERE RN =1
you can try this:
SELECT DISTINCT
USER_ID,
LAR.LastArrive
FROM time_recording as tr
CROSS APPLY (
SELECT
MAX(Arrive) as LastArrive
FROM time_recording as ta
WHERE
tr.USER_ID = ta.USER_ID AND
ta.Arrive IS NOT NULL
) as LAR

SQL Percentage calculation

Is it possible in SQL to calculate the percentage of the 'StaffEntered' column's "Yes" values (case when calculated column) out of the grand total number of orders by that user (RequestedBy)? I'm basically doing this function now myself in Excel with a Pivot table, but thought it may be easier to build it into the query. Here is the existing sample SQL code:
Select
Distinct
RequestedBy = HStaff.Name,
AccountID = isnull(pv.AccountID, ''),
StaffEntered = Case When DictionaryItem2.Name like '%PLB%' Then 'Yes' Else 'No' end
FROM
[dbo].[HOrd] HOrd WITH ( NOLOCK )
left outer join HStaff HStaff with (nolock)
on HOrd.Requestedby_oid = HStaff.ObjectID
and HStaff.Active = 1
left outer join DictionaryItem DictionaryItem2 WITH (NOLOCK)
ON HSUser1.PreferenceGroup_oid = DictionaryItem2.ObjectID
AND DictionaryItem2.ItemType_oid = 98
Here is what I am doing in Excel currently with the query results, I have a pivot table and I am dividing the "Yes" values of the "StaffEntered" field out of the Grand Total number of entries for that specific "RequestedBy" user. Essentially Excel is doing the summarization and then I am doing a simple division calculation to obtain the percentage.
Thanks in advance!
You didn't provide a lot in the way of details but I think this should be pretty close to what you are looking for.
select HStaff.Name as RequestedBy
, isnull(pv.AccountID, '') as AccountID
, Case When DictionaryItem2.Name like '%PLB%' Then 'Yes' Else 'No' end as StaffEntered
, sum(Case When DictionaryItem2.Name like '%PLB%' Then 1 Else 0 end) / GrandTotal
From SomeTable
group by HStaff.Name
, isnull(pv.AccountID, '')
, GrandTotal
Giving the FROM part of your SQL Statement would allow us to create a more correct answer. This statement will get the totals of yes/no per HStaff name and add it to each detail record in your SQL statement:
WITH cte
AS ( SELECT HStaff.Name ,
SUM(CASE WHEN dictionaryItem2.Name LIKE '%PLB%' THEN 1
ELSE 0
END) AS YesCount ,
SUM(CASE WHEN dictionaryItem2.Name NOT LIKE '%PLB%'
THEN 1
ELSE 0
END) AS NotCount
FROM YourTable
GROUP BY HStaff.Name
)
SELECT HStaff.Name AS requestedBy ,
ISNULL(pv.AccountID, '') AS AccountID ,
CASE WHEN DictionaryItem2.Name LIKE '%PLB%' THEN 'Yes'
ELSE 'No'
END AS StaffEntered ,
cte.YesCount / ( cte.YesCount + cte.NotCount ) AS PLB_Percentage
FROM yourtable
INNER JOIN cte ON yourtable.Hstaff.Name = cte.NAME

Calculated summary field based on child table

I have two tables, Order and OrderItem. There is a one-to-many relationship on Order.Order_ID=OrderItem.Order_ID
I want a query to return a list showing the status of each Order, COMPLETE or INCOMPLETE.
A COMPLETE Order is defined as one where all the related OrderItem records have a non-NULL, non-empty value in the OrderItem.Delivery_ID field.
This is what I have so far:
SELECT Order.Order_ID, 'INCOMPLETE' AS Order_status
FROM Order
WHERE EXISTS
(SELECT *
FROM OrderItem
WHERE OrderItem.Order_ID=Order.Order_ID
AND (OrderItem.Delivery_ID IS NULL OR OrderItem.Delivery_ID=''))
UNION
SELECT Order.Order_ID, 'COMPLETE' AS Order_status
FROM Order
WHERE NOT EXISTS
(SELECT *
FROM OrderItem
WHERE OrderItem.Order_ID=Order.Order_ID
AND (OrderItem.Delivery_ID IS NULL OR OrderItem.Delivery_ID=''))
ORDER BY Order_ID DESC
It works, but runs a bit slow. Is there a better way?
(N.B. I've restated the problem for clarity, actual table and field names are different)
I would suggest you have a column status on your Order table and update the status to complete when all order items get delivered.
It will make simple your query to get status as well improve performance.
Put it into a subquery to try to make the case statement less confusing:
SELECT Order_ID,
CASE WHEN incomplete_count > 0 THEN 'INCOMPLETE' ELSE 'COMPLETE' END
AS Order_status
FROM ( SELECT o.Order_ID
,SUM( CASE WHEN OrderItem.Delivery_ID IS NULL OR OrderItem.Delivery_ID='' THEN 1 ELSE 0 END )
AS incomplete_count
FROM Order o
INNER JOIN OrderItem i ON (i.Order_ID = o.Order_ID)
GROUP by o.Order_ID
) x
ORDER BY ORder_ID DESC
The idea is to keep a counter every time you encounter a null item. If the sum is 0, there were no empty order items.
Try this one -
SELECT
o.Order_ID
, Order_status =
CASE WHEN ot.Order_ID IS NULL
THEN 'COMPLETE'
ELSE 'INCOMPLETE'
END
FROM dbo.[Order] o
LEFT JOIN (
SELECT DISTINCT ot.Order_ID
FROM dbo.OrderItem ot
WHERE ISNULL(ot.Delivery_ID, '') = ''
) ot ON ot.Order_ID = o.Order_ID

Using COUNT() in WHERE Clause

I have the following SQL statement:
SELECT C.LINKED_TABLE_ID AS CLIENT_DIWOR, I.STATUS AS AML_STATUS, dbo.CLIENT_MASTER.CLIENTCODE
FROM AML_INFORMATION AS I INNER JOIN
dbo.COMM_ENTRY AS C ON C.NAME_ID = I.CONTACT_ID AND C.TABLE_ID = 'C' AND C.PRIMARY_FLAG = 'Y' INNER JOIN
dbo.CLIENT_MASTER ON C.LINKED_TABLE_ID = dbo.CLIENT_MASTER.DIWOR
WHERE I.CONTACT_ID = 234
AND I.[STATUS] = 'CC'
AND (CLIENT_MASTER.DIWOR = I.CONTACT_ID)
AND (CLIENT_MASTER.POSTING_STATUS <> '')
AND ((SELECT COUNT(CONTACT_ID) FROM AML_ID_DOCUMENT GROUP BY CONTACT_ID HAVING CONTACT_ID = 234) >1)
If I run this it returns 0 records, however if I remove the last AND statement AND ((SELECT COUNT(CONTACT_ID) FROM AML_ID_DOCUMENT GROUP BY CONTACT_ID HAVING CONTACT_ID = 234) >1) it returns the records I would expect.
Is it possible to use a COUNT() in this way? Incidentally, the COUNT() in this example returns 2 records and if I include it in the SELECT statement I also get 0 records returned.
Can anyone point me in the right direction?
Thanks in advance.
Your showed Script should never return anything ...
your having part could look this way
and (Select Count(*) from AML_ID_DOCUMENT where CONTACT_ID =I.CONTACT_ID)>1
though ist should work as it is...
Shouldn't the last part be like this:
AND EXISTS (SELECT CONTACT_ID FROM AML_ID_DOCUMENT
WHERE CONTACT_ID = 234
GROUP BY CONTACT_ID
HAVING COUNT(CONTACT_ID)>1)
Try this query:
select count(portfolio_id) as porfolioCount
from engineering_module_tracker_v2
where r0_approval__category='Cat I' & 'Cat II';
Cat means category-wise.

query doesn't return proper value

I have a query as given below:
SELECT DISTINCT(FldStrategyID), FldTradeServerName,FldBaseDir,FldBinaryStartTime
FROM TblOrders Ord,
(SELECT CONCAT(FldStrategyID,'.',FldTradeServerName,'.',FldBaseDir,'.',FldBinaryStartTime) strid
FROM TblOrders
GROUP BY FldStrategyID) as OrderView
WHERE Ord.FldStrategyID !=''
AND OrderView.strid NOT IN (SELECT FldStrategyID FROM TblStrategyMasters WHERE 1)
The problem is that this part is not working:
OrderView.strid NOT IN (SELECT FldStrategyID FROM TblStrategyMasters WHERE 1)
I think that the quotes(') are missing somewhere.

Resources