I have a requirement which I need to produce the result that returns alternately 1 and 0.
SELECT *
FROM
(SELECT
id
,itemNo
,convert(int,tStationsType_id) as tStationsType_id
,tSpecSetpoint_descriptions_id
,SetpointValue
,rowEvenOdd
FROM
TEST S
INNER JOIN
(SELECT
itemNo AS IM, tStationsType_id as ST,
ROW_NUMBER() OVER(PARTITION BY itemNo ORDER BY itemNo) % 2 AS rowEvenOdd
FROM TEST
GROUP BY itemNo, tStationsType_id) A ON S.itemNo = A.IM
AND S.tStationsType_id = A.ST) t
WHERE
itemno = '1000911752202'
ORDER BY
tStationsType_id
The result I get is something like below.
I would like to produce alternate 1 and 0 in rowEvenOdd. However I notice it I can't get it alternate if I order by tStationsType_id.
So basically, what I want is when the
StationsType_id = 2, then rowEvenOdd = 0
StationsType_id = 3, then rowEvenOdd = 1
StationsType_id = 6, then rowEvenOdd = 0
StationsType_id = 8, then rowEvenOdd = 1
StationsType_id = 10, then rowEvenOdd = 0
Can someone help me with this query?
Thanks.
If you just need alternating 0 and 1 in the result set, use SEQUENCE like this:
CREATE SEQUENCE EvenOdd
START WITH 0
INCREMENT BY 1
MAXVALUE 1
MINVALUE 0
CYCLE;
GO
SELECT SalesId, NEXT VALUE FOR EvenOdd as EvenOddColumn FROM Sales
DROP SEQUENCE EvenOdd
To learn more, go to the MSDN page on sequences here: https://msdn.microsoft.com/en-us/library/ff878091.aspx
you can Use case when then
SELECT
case
when exists (SELECT 1 FROM StationsTypeMaster
M WHERE M.StationsType_id=A.StationsType_id)
then 1
else 0 end as rowEvenOdd
,*
FROM
(
select id
,itemNo
,convert(int,tStationsType_id) as tStationsType_id
,tSpecSetpoint_descriptions_id
,SetpointValue
,rowEvenOdd from TEST S
inner join
(select itemNo AS IM,tStationsType_id as ST,
ROW_NUMBER() OVER(PARTITION BY itemNo ORDER BY itemNo)%2 AS rowEvenOdd
from TEST
group by itemNo,tStationsType_id
)A
on S.itemNo = A.IM
and S.tStationsType_id = A.ST) t
where itemno = '1000911752202'
order by tStationsType_id
Use DENSE_RANK instead of ROW_NUMBER:
SELECT * FROM
(
SELECT
id,
itemNo
convert(int,tStationsType_id) as tStationsType_id,
tSpecSetpoint_descriptions_id,
SetpointValue,
(DENSE_RANK() OVER(ORDER BY CAST(A.ST as INT)) - 1)%2 AS rowEvenOdd
FROM
TEST S
JOIN
(
SELECT
itemNo AS IM,
tStationsType_id as ST
FROM
TEST
GROUP BY
itemNo,tStationsType_id
)A
ON
S.itemNo = A.IM
and S.tStationsType_id = A.ST
) t
WHERE
itemno = '1000911752202'
ORDER BY
tStationsType_id
Related
Just a question on displaying a row on flight level and displaying a count on how many crew members on that flight.
I want to change the output so it will only display a single record at flight level and it will display two additional columns. One column (cabincrew) is the count of crew members that have the 'CREWTYPE' = 'F' and the other column (cockpitcrew) is the count of crew members that have the `'CREWTYPE' = 'C'.
So the query result should look like:
Flight DepartureDate DepartureAirport CREWBASE CockpitCrew CabinCrew
LS361 2016-05-19 BFS BFS 0 3
Can I have a little help tweaking the below query please:
WITH CTE AS (
SELECT cd.*, c.*, l.Carrier, l.FlightNumber, l.Suffix, l.ScheduledDepartureDate, l.ScheduledDepartureAirport
FROM
(SELECT *, ROW_NUMBER() OVER(PARTITION BY LegKey ORDER BY UpdateID DESC) AS RowNumber FROM Data.Crew) c
INNER JOIN
Data.CrewDetail cd
ON c.UpdateID = cd.CrewUpdateID
AND cd.IsPassive = 0
AND RowNumber = 1
INNER JOIN
Data.Leg l
ON c.LegKey = l.LegKey
)
SELECT
sac.Airline + CAST(sac.FlightNumber AS VARCHAR) + sac.Suffix AS Flight
, sac.DepartureDate
, sac.DepartureAirport
, sac.CREWBASE
, sac.CREWTYPE
, sac.EMPNO
, sac.FIRSTNAME
, sac.LASTNAME
, sac.SEX
FROM
Staging.SabreAssignedCrew sac
LEFT JOIN CTE cte
ON sac.Airline + CAST(sac.FlightNumber AS VARCHAR) + sac.Suffix = cte.Carrier + CAST(cte.FlightNumber AS VARCHAR) + cte.Suffix
AND sac.DepartureDate = cte.ScheduledDepartureDate
PLEASE TRY THIS.
SELECT Flight,
DepartureDate,
DepartureAirport,
CREWBASE,
SUM(CASE WHEN CREWTYPE = 'F' THEN 1 ELSE 0 END) AS CabinCrew ,
SUM(CASE WHEN CREWTYPE = 'C' THEN 1 ELSE 0 END) AS CockpitCrew
FROM #Table
GROUP BY Flight, DepartureDate, DepartureAirport, CREWBASE
Please Try This:
select Flight, DepartureDate, DepartureAirport,CREWBASE,
count(case when CREWTYPE='F' then 1 end ) as CabinCrew,count(case when CREWTYPE='C' then 1 end ) as CockpitCrew
from Staging.SabreAssignedCrew
group by Flight, DepartureDate, DepartureAirport,CREWBASE
I have a table like this
Test_order
Order Num Order ID Prev Order ID
987Y7OP89 919325 0
987Y7OP90 1006626 919325
987Y7OP91 1029350 1006626
987Y7OP92 1756689 0
987Y7OP93 1756690 0
987Y7OP94 1950100 1756690
987Y7OP95 1977570 1950100
987Y7OP96 2160462 1977570
987Y7OP97 2288982 2160462
Target table should be like below,
Order Num Order ID Prev Order ID
987Y7OP89 919325 0
987Y7OP90 1006626 919325
987Y7OP91 1029350 1006626
987Y7OP92 1756689 1029350
987Y7OP93 1756690 1756689
987Y7OP94 1950100 1756690
987Y7OP95 1977570 1950100
987Y7OP96 2160462 1977570
987Y7OP97 2288982 2160462
987Y7OP97 2288900 2288982
Prev Order ID should be updated with the Order ID from the previous record from the same table.
I'm trying to create a dummy data set and update..but it's not working..
WITH A AS
(SELECT ORDER_NUM, ORDER_ID, PRIOR_ORDER_ID,ROWNUM RID1 FROM TEST_ORDER),B AS (SELECT ORDER_NUM, ORDER_ID, PRIOR_ORDER_ID,ROWNUM+1 RID2 FROM TEST_ORDER)
SELECT A.ORDER_NUM,B.ORDER_ID,A.PRIOR_ORDER_ID,B.PRIOR_ORDER_ID FROM A,B WHERE RID1 = RID2
You could use Oracles Analytical Functions (also called Window functions) to pick up the value from the previous order:
UPDATE Test_Order
SET ORDERID = LAG(ORDERID, 1, 0) OVER (ORDER BY ORDERNUM ASC)
WHERE PrevOrderId = 0
See here for the documentation on LAG()
In sql-server you cannot use window function in update statement, not positive but don't think so in Oracle either. Anyway to get around that you can just update a cte as follows.
WITH cte AS (
SELECT
*
,NewPreviousOrderId = LAG(OrderId,1,0) OVER (ORDER BY OrderNum)
FROM
TableName
)
UPDATE cte
SET PrevOrderId = NewPreviousOrderId
And if you want to stick with the ROW_NUMBER route you were going this would be the way of doing it.
;WITH cte AS (
SELECT
*
,ROW_NUMBER() OVER (ORDER BY OrderNum) AS RowNum
FROM
TableName
)
UPDATE c1
SET PrevOrderId = c2.OrderId
FROM
cte c1
INNER JOIN cte c2
ON (c1.RowNum - 1) = c2.RowNum
Here's the background, I have a set of rows:
I only want to get the first ADVANCE after every RECOVERY in the type column per accountid
so I the result should be the advances with procdates
2015-09-03 09:55:12.228343
2015-09-04 23:10:42.016903
Is this possible in one query?
Try this:
WITH CTE_PrevType
AS (
SELECT accountid
,procdate
,LAG(type, 1, NULL) OVER (
ORDER BY procdate
) AS PreviousType
FROM < Table_Name >
)
SELECT
accountid
,procdate
,type
,value
FROM < Table_Name > AS TN
INNER JOIN CTE_PrevType CPT
ON TN.accountid = CPT.accountid
AND TN.procdate = CPT.procdate
WHERE TN.type = 'ADVANCE'
AND CPT.type = 'RECOVERY'
I Have found on how to get it!
SELECT * FROM
(SELECT accountid,
procdate,
type,
value,
LAG(type) OVER (ORDER BY procdate ASC) AS previousType
FROM transaction) w WHERE previousType = 'RECOVERY';
I have following table:
Card(
MembershipNumber,
EmbossLine,
status,
EmbossName
)
with sample data
(0009,0321,'E0','Finn')
(0009,0322,'E1','Finn')
(0004,0356,'E0','Mary')
(0004,0398,'E0','Mary')
(0004,0382,'E1','Mary')
I want to retrieve rows such that only those rows should appear that have count of MembershipNumber > 1 AND count of status='E0' > 1.
For Example The query should return following result
(0004,0356,'E0','Mary')
(0004,0398,'E0','Mary')
I have the query for filtering it with MembershipNumber count but cant figure out how to filter by status='E0'. Here's the query so far
SELECT *
FROM (SELECT *,
Count(MembershipNumber)OVER(partition BY EmbossName) AS cnt
FROM card) A
WHERE cnt > 1
You can just add WHERE status = 'E0' inside your subquery:
SQL Fiddle (credit to Raging Bull for the fiddle)
SELECT *
FROM (
SELECT *,
COUNT(MembershipNumber) OVER(PARTITION BY EmbossName) AS cnt
FROM card
WHERE status = 'E0'
)A
WHERE cnt > 1
You can do it this way:
select t1.*
from card t1 left join
(select EmbossName
from card
where [status]='E0'
group by EmbossName,[status]
having count(MembershipNumber)>1 ) t2 on t1.EmbossName=t2.EmbossName
where t2.EmbossName is not null and [status]='E0'
Result:
MembershipNumber EmbossLine status EmbossName
---------------------------------------------------
4 356 E0 Mary
4 398 E0 Mary
Sample result in SQL Fiddle
try :
WITH cnt AS (
SELECT MembershipNumber, status
FROM Card
WHERE status = 'E0'
GROUP BY MembershipNumber, status
HAVING COUNT(MembershipNumber) > 1 AND COUNT(status) > 1
)
SELECT c.*
FROM Card c
INNER JOIN cnt
ON c.MembershipNumber = cnt.MembershipNumber
AND c.status = cnt.status;
You can try this:
DECLARE #DataSource TABLE
(
[MembershipNumber] SMALLINT
,[EmbossLine] SMALLINT
,[status] CHAR(2)
,[EmbossName] VARCHAR(8)
);
INSERT INTO #DataSource ([MembershipNumber], [EmbossLine], [status], [EmbossName])
VALUES (0009,0321,'E0','Finn')
,(0009,0322,'E1','Finn')
,(0004,0356,'E0','Mary')
,(0004,0398,'E0','Mary')
,(0004,0382,'E1','Mary');
SELECT [MembershipNumber]
,[EmbossLine]
,[status]
,[EmbossName]
FROM
(
SELECT *
,COUNT([MembershipNumber]) OVER (PARTITION BY [EmbossName]) AS cnt1
,SUM(IIF([status] = 'E0' , 1, 0)) OVER (PARTITION BY [EmbossName]) AS cnt2
FROM #DataSource
) DS
WHERE cnt1 > 1
AND cnt2 > 1
AND [status] = 'E0';
The idea is to add a second counter, but instead of COUNT function to use SUM function for counting only the rows that have [status] = 'E0'. Then, in the where clause we are filtering by the two counters and [status] = 'E0'.
I currently have the following query
SELECT organisation.organisationID, COUNT(organisation.organisationID)
FROM position, positionLocation, organisation
WHERE position.positionLocationID = positionLocation.positionLocationID AND
positionLocation.organisationID = organisation.organisationID AND
position.status = 'Open'
GROUP BY organisation.organisationID;
This query outputs
organisationID | countOrganisationID
1 3
3 2
5 3
I would like to display records that have max countOrganisationID. Ideally i would just like output the organisationID with its corresponding organisationName if possible.
Something along the lines of
organisationID | organisatioName
1 name1
5 name2
Any help would be appreciate
Thanks
Barrett is right, RANK() is the way to go, e.g.:
SELECT organisationID, c FROM (
SELECT organisationID
,c
,RANK() OVER (ORDER BY c DESC) r
FROM (
SELECT organisation.organisationID
,COUNT(organisation.organisationID) AS c
FROM position, positionLocation, organisation
WHERE position.positionLocationID = positionLocation.positionLocationID
AND positionLocation.organisationID = organisation.organisationID
AND position.status = 'Open'
GROUP BY organisation.organisationID
)
) WHERE r = 1;
Could just subquery it:
WITH counts AS (
SELECT organisation.organisationID
,organisation.organisationName
,COUNT(organisation.organisationID) the_count
FROM position, positionLocation, organisation
WHERE position.positionLocationID = positionLocation.positionLocationID
AND positionLocation.organisationID = organisation.organisationID
AND position.status = 'Open'
GROUP BY organisation.organisationID, organisation.organisationName
)
SELECT organisationID, organisationName
FROM counts
WHERE the_count = (SELECT MAX(the_count) FROM counts)
This should work.
SELECT organisationID, organisatioName
FROM position, positionLocation, organisation
WHERE position.positionLocationID = positionLocation.positionLocationID AND
positionLocation.organisationID = organisation.organisationID AND
position.status = 'Open'
AND COUNT(organisation.organisationID) =
SELECT MAX(cnt) AS MaxCnt FROM
SELECT organisation.organisationID, COUNT(organisation.organisationID) AS cnt
FROM organisation
WHERE position.status = 'Open'
GROUP BY organisation.organisationID
GROUP BY organisation.organisationID, organisation.organisatioName;