Exclude records when a DisposalState is set to "Disposed-off" from "Pending" in SQL - sql-server-2008-r2

SELECT *
FROM [Main_Cause_List]
WHERE DisposalState is 'Disposed-off';
I want to to hide those rows whose case status is changed to "Pending" from case status "Disposed-off". As one case is Disposed-off, then I no need to show that case that in the pending case list.
Basically I will make two lists: (1) for pending case list and (2) for disposed-off list.
For example: once a case fixed for a date=08-05-2021 at that time its DisposalStatus was Pending but in the same date the same Disposed-off.
So when I make BarType Chart then on the same it show me that case in pending list too...how to avoid that case which has been disposed-off...

It seems you want to remove from your result all CaseNo for which there is at least one row with DisposalState = 'Dispossed-off'. You can use a windowed conditional COUNT for this.
SELECT *
FROM (
SELECT *,
COUNT(CASE WHEN DisposalState = 'Dispossed-off' THEN 1 END)
OVER (PARTITION BY CaseNo) CountDisposed
FROM [Main_Cause_List]
) m
WHERE CountDisposed = 0;

Related

How to get median for time interval in Postgres? [duplicate]

I have the following query:
SELECT
title,
(stock_one + stock_two) AS global_stock
FROM
product
ORDER BY
global_stock = 0,
title;
Running it in PostgreSQL 8.1.23 i get this error:
Query failed: ERROR: column "global_stock" does not exist
Anybody can help me to put it to work? I need the availale items first, after them the unnavailable items. Many thanks!
You can always ORDER BY this way:
select
title,
( stock_one + stock_two ) as global_stock
from product
order by 2, 1
or wrap it in another SELECT:
SELECT *
from
(
select
title,
( stock_one + stock_two ) as global_stock
from product
) x
order by (case when global_stock = 0 then 1 else 0 end) desc, title
One solution is to use the position:
select title,
( stock_one + stock_two ) as global_stock
from product
order by 2, 1
However, the alias should work, but not necessarily the expression. What do you mean by "global_stock = 0"? Do you mean the following:
select title,
( stock_one + stock_two ) as global_stock
from product
order by (case when global_stock = 0 then 1 else 0 end) desc, title
In case anyone finds this when googling for whether you can just ORDER BY my_alias: Yes, you can. This cost me a couple hours.
As the postgres docs state:
The ordinal number refers to the ordinal (left-to-right) position of the output column. This feature makes it possible to define an ordering on the basis of a column that does not have a unique name. This is never absolutely necessary because it is always possible to assign a name to an output column using the AS clause.
So either this has been fixed since, or this question is specifically about the ORDER BY my_alias = 0, other_column syntax which I didn't actually need.

Getting a BIT value as to whether a non-Aggregated Value is in a constant list

Given the following tables:
Logs
-Id
-SuperLogId
-ScanMode
Super Log
-Id
-Name
How do I write the following query to get 1 for the Logs from SuperLogs where the Log has a ScanMode of "Navigational", "Locatable" or "Automatic" and 0 otherwise?
SELECT Name,
CAST
(
CASE WHEN
Logs.ScanMode IN
(
'Navigational',
'Locatable',
'Automatic'
)
THEN
1
ELSE
0
END
AS BIT
) HasLogsWithGpsData
FROM SuperLogs
INNER JOIN Logs ON Logs.SuperLogId = SuperLogs.Id
GROUP BY SuperLogs.Id
The above query just gives me this error instead of working:
Column 'Logs.ScanMode' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I want to check whether any of the ScanModes are in that list, not some accumulated version of them, so I don't want to pre-aggregate these values.
The Logs and SuperLogs tables have a one-to-many relationship. This means that for each record in SuperLogs there can be many records in Logs. This is why your query doesn't make sense and can't work as is.
The way I understand the question is this: If Any Log that belongs to the current SuperLog
have a ScanMode that is either one of the values in the list, you want to get 1. If none of them have a ScanMode that fits the list, you want to get 0.
If that is correct, a simple solution would be using conditional aggregation:
SELECT Name,
CAST
(
MAX(
CASE WHEN
Logs.ScanMode IN
(
'Navigational',
'Locatable',
'Automatic'
)
THEN
1
ELSE
0
END
)
AS BIT
) AS HasLogsWithGpsData
FROM SuperLogs
INNER JOIN Logs ON Logs.SuperLogId = SuperLogs.Id
GROUP BY SuperLogs.Id

Returning max version number per interval period timestamp

I have a dataset with the following fields:
IntervalPeriodTimestamp
RegisterTypeCode
ReadingReplacementVersion
IntervalValue
I receive readings every 30 minutes but sometimes these readings are replaced and the readingreplacementversionumber is incremented.
Using LINQ how can I return only a list of the largest reading replacementversion for each half hourly period?
I have tried:
db.IntervalInformations
.Where(ii => ii.ChannelInformation.RegisterTypeCode == "62")
.OrderBy(ii => ii.IntervalPeriodTimestamp)
.ThenBy(ii => ii.ChannelInformation.Meter.messageType342.ReadingReplacementVersionNumber)
.ToList();
This returns a list sorted by Interval Period Timestamp and then by Replacement Version but I only want to return the list of interval informations with the MAX one. I have been able to achieve this in SQL using code:
WITH CTE AS
(
select SerialNumber, RegisterTypeCode, IntervalStatusCode, UOM_Code,
IntervalPeriodTimestamp, ReadingReplacementVersionNumber, IntervalValue,
RN = ROW_NUMBER()
OVER (PARTITION BY IntervalPeriodTimestamp
ORDER BY ReadingReplacementVersionNumber desc)
from MarketMessage as a
inner join messageType342 as b on a.MarketMessageID = b.MarketMessageID
inner join Meter as c on b.messageType342ID = c.MessageType342ID
inner join ChannelInformation as d on c.MeterID = d.MeterID
inner join IntervalInformation as e on d.ChannelInformationID = e.ChannelInformationID
where MPRN = 101010101010
and CAST(IntervalPeriodTimestamp as date) between '1 feb 2018' and '28 feb 2018'
and RegisterTypeCode = 62
)
select * from CTE
WHERE RN = 1
Not sure how I can convert this to LINQ statement
Try something like this: group your items into the different groups from which you want only one record, order the records by ReadingReplacementVersionNumber in descendent order, and get the first record in each group. Easier to understand with some code:
db.IntervalInformations
.Where(ii => ii.ChannelInformation.RegisterTypeCode == "62")
.OrderByDescending(ii => ii.ReadingReplacementVersionNumber )
.GroupBy(x => new { x.SerialNumber, x.RegisterTypeCode, x.IntervalStatusCode })
.Select(g => g.First());
The list of properties in GroupBy in your real query may be different. You have to define correctly the criteria for composing the groups. Include in the GroupBy list the combination of properties that will have the same value in each one of your groups, and different values in other groups.

OrientDB: Find Connected Components Values during the visit

I have schema with 3 main classes: Transaction , Address and ValueTx(Edge).
I am trying to find connected components within a range of time.
Now I am doing this query based on this one ( OrientDB: connected components OSQL query) :
SELECT distinct(traversedElement(0)) from ( TRAVERSE both('ValueTx') from (select * from Transaction where height >= 402041 and height <= 402044))
And this returns the rid of the 'head' of each trasversal and from it doing another DFS I can get every node and edge of the connected component I want to search about.
How can I, using the query above, also get the number of the transactions within the connected component and also the sum of their values? (The value of a tx is a property of the class Transaction)
I want to do something like:
SELECT distinct(traversedElement(0)) as head, count(Transaction), sum(valueTot) from ( TRAVERSE both('ValueTx') from (select * from Transaction where height >= 402041 and height <= 402044)) group by head
But of course is not working. I get only one row with the last head and the sum of all the transactions.
Thanks in advance.
Edit:
This is an example of what I'm looking for:
Connected Transactions
Every transaction there is within the same range of height:
Using my query ( the first one in my post) I get the rid of the first node of each group of transaction that are linked through several addresses.
example:
#15:27
#15:28
#15:30
#15:34
#15:35
#15:36
#15:37
#15:41
#15:47
#15:53
What I'm trying to get is a list of every first node with the total number of transactions (not addresses only the transaction) of the group it belongs to and the sum of the value of every Transaction (stored in valueTot inside the class transaction.
Edit2:
This is the dataset where I am making the tests:
The main problem is that I have a lot of data and the approach I was trying before (from every rid I make a different sql query) it's quite slow, I hope there is a faster way.
Edit3:
This is an updated sample db: Download
(note, it's way larger than the other)
select head, sum(valueTot) as valueTot, count(*) as numTx,sum(miner) as minerCount from (SELECT *,traversedElement(0) as head from ( TRAVERSE both('ValueTx') from (select * from Transaction where height >= 0 and height <= 110000 ) while ( #class = 'Address' or (#class = 'Transaction' and height >= 0 and height <= 110000 )) ) where #class = 'Transaction' ) group by head
This query on my system takes around one minute, also if I limit the result set, so I think the problem maybe in the internal query that selects the transactions that isn't using the indexes... Do you have any idea?
You can use this query
select #rid, $a[0].sum as sumValueTot ,$a[0].count as countTransaction from Transaction
let $a = ( select sum(valueTot),count(*) from (TRAVERSE both('ValueTx') from $parent.$current) where #class="Transaction")
where height >= 402041 and height <= 402044
Hope it helps.
is this what are you looking for?
select head, sum(valueTot), count(*) from (SELECT *,traversedElement(0) as head from ( TRAVERSE both('ValueTx') from (select * from Transaction where height >= 402041 and height <= 402044)) where #class = "Transaction") group by head

it is possible to concatenate one result set onto another in a single query?

I have a table of Verticals which have names, except one of them is called 'Other'. My task is to return a list of all Verticals, sorted in alpha order, except with 'Other' at the end. I have done it with two queries, like this:
String sqlMost = "SELECT * from core.verticals WHERE name != 'Other' order by name";
String sqlOther = "SELECT * from core.verticals WHERE name = 'Other'";
and then appended the second result in my code. Is there a way to do this in a single query, without modifying the table? I tried using UNION
(select * from core.verticals where name != 'Other' order by name)
UNION (select * from core.verticals where name = 'Other');
but the result was not ordered at all. I don't think the second query is going to hurt my execution time all that much, but I'm kind of curious if nothing else.
UNION ALL is the usual way to request a simple concatenation; without ALL an implicit DISTINCT is applied to the combined results, which often causes a sort. However, UNION ALL isn't required to preserve the order of the individual sub-results as a simple concatenation would; you'd need to ORDER the overall UNION ALL expression to lock down the order.
Another option would be to compute an integer order-override column like CASE WHEN name = 'Other' THEN 2 ELSE 1 END, and ORDER BY that column followed by name, avoiding the UNION entirely.