Count Distinct values in one column based on other column - sql

I am trying to count distinct values on Z_l based on value by using with clause. Sample data exercise included below.
please look at the picture, the distinct values of Z_l based on X='ny'
with distincz_l as (select ny.X, ny.z_l o.cnt From HOPL ny join (select X, count(*) as cnt from HOPL group by X) o on (ny.X = o.Z_l)) select * from HOPL;

You don't even need a WITH clause, since you just need one single sentence:
SELECT z_l, count(1)
FROM hopl
WHERE x='ny'
GROUP BY z_l
;

Related

How to include column not included in Group By

I have the table DirectCosts with the following columns:
DetailsID (unique)
InvoiceNumber
ProjectID
PayableID
I need to find the duplicates combinations of payableid and invoicenumber.
How can I adjust the following query so that it accommodates the combination AND displays the list of instead of the count?
SELECT sinvoicenumber, count(*)
FROM exportdirectcostdetails where iprocoreprojectid = 1187294
GROUP BY sinvoicenumber
HAVING COUNT(*) > 2
Is there a way it can display all columns?
Original Question : Why do I get error ed2 should have column name defined
You are having a derived table, so you need to have column names for the derived table.
select ed1.sinvoicenumber,
ed1.ipayableid,
ed2.sinvoicenumber
from ExportDirectCostDetails ed1
inner join
(
SELECT sinvoicenumber, count(sinvoicenumber) AS InvoiceNumberCount
FROM exportdirectcostdetails
where iprocoreprojectid = 1187294
GROUP BY sinvoicenumber
HAVING COUNT(*) > 2
) ed2
on ed1.sinvoicenumber = ed2.sinvoicenumber
Updated Question: How to have all column names
You need to have PARTITION BY clause defined and then apply filter as given below:
SELECT t.* FROM
(SELECT *, count(*) OVER(PARTITION BY payableid,invoiceNumber) AS InvoiceCount
FROM exportdirectcostdetails where iprocoreprojectid = 1187294) as t
WHERE InvoiceCount > 1

How to count the number of distinct values for each specific

I have a database containing two separate fields A and B. I want to find out if for any given value of A there are multiple rows with different values of B.
I have tried using group by and distinct but I am doing something wrong, because I keep getting results which, when I query the specific value of A, all the values of B are the same. I have tried variants on the following including:
SELECT COUNT(B) FROM ex1 GROUP BY A HAVING COUNT(*) > 1;
SELECT COUNT(DISTINCT B) FROM ex1 GROUP BY A HAVING COUNT(DISTINCT B) > 1;
Strangely, this last one wound up giving me results where for a given value of B there were multiple values of A, which is backwards from what I wanted. I tried reversing A and B in the last query but that wound up giving me cases where A only had a single value of B.
How can I get records for only where there is a specific value of A in multiple records, each of which has a different value for B?
Give this a try:
"records for only where there is a specific value of A in multiple records, each of which has a different value for B?"
SELECT DISTINCT ex1a.A
FROM ex1 ex1a
WHERE
(SELECT COUNT(ex1b.B) FROM ex1 ex1b WHERE ex1a.A=ex1b.A)
= (SELECT COUNT(DISTINCT ex1b.B) FROM ex1 ex1b WHERE ex1a.A=ex1b.A)
AND
(SELECT COUNT(ex1c.B) FROM ex1 ex1c WHERE ex1a.A = ex1c.A) > 1
And, you can remove the last SELECT if you want to include the case where there is just 1 (distinct) record for A and B.
this should work:
create table want as
select a,b,count(*)as cnt from(
select a,b,count(*) as num from have
group by a, b)
group by a having cnt > 1;

Adding new column of total_event

I want to append virtual column in SELECT result with the name of total_event which will be total of same type of wait_event_type, As shown in the screenshot I want to sum 'Lock' which will be 18+2 = 20 and add that against all Lock type column.
I have a event_stats table with three columns wait_event_type, wait_event, event_count which holds all the data.
You can use a window function to do this:
SELECT
wait_event_type,
wait_event,
event_count,
SUM(event_count) OVER (PARTITION BY wait_event_type) AS total_event_count
FROM my_table
You can also use group by clause and join
select m.wait_event_type,
m.wait_event,
m.event_count,
t.total_event_count from (select wait_event_type,SUM(event_count) as total_event_count
from my_table group by wait_event_type)t join my_table m on
m.wait_event_type=t.wait_event_type

SQL Oracle - query to return rows based on data matchng rules

I have the below data
NUMBER SEQUENCE_NUMBER
CA00000045 AAD508
CA00000045 AAD508
CA00000046 AAD509
CA00000047 AAD510
CA00000047 AAD510
CA00000047 AAD511
CA00000048 AAD511
and I would like to find out which rows do not match the following rule:
NUMBER will always be the same when the SEQUENCE_NUMBER is the same.
So in the above data 'AAD508' will mean the NUMBER value will be the same on each row where the same value appears in the SEQUENCE_NUMBER.
I want to right a query that will bring me back rows where this rule is
broken. So for example:
CA00000047 AAD511
CA00000048 AAD511
I don't know where to start with this one, so have no initial SQL i'm afraid.
Thanks
You want to self join on the data to compare each row to all others sharing the same sequence number, and then filter using a with statement to only get rows with non-matching numbers. You did not give a name for the table so I added it as "table_name" below
SELECT
a.NUMBER,
a.SEQUENCE_NUMBER
FROM table_name a
INNER JOIN table_name b
ON a.SEQUENCE_NUMBER = b.SEQUENCE_NUMBER
WHERE a.NUMBER <> b.NUMBER
GROUP BY 1,2
Threw in the group by to act as a distinct
I would simply use exists:
select t.*
from t
where exists (select 1
from t t2
where t2.sequence_number = t.sequence_number and
t2.number <> t.number
);
If sequence_numbers() only had up to two rows, you could get each rule-breaker on one row:
select sequence_number, min(number), max(number)
from t
group by sequence_number
having min(number) <> max(number);
Or, you could generalize this to get the list of numbers on a single row:
select sequence_number, listagg(number, ',') within group (order by number) as numbers
from t
group by sequence_number
having min(number) <> max(number);

Select number of records until the sum is less than 'n' - Access SQL

I am working on Microsoft Access. My requirement is, User will give any percentage value and I have to find the number of IDs which form the percentage of the 'Value' column. For e.g. in the below DataSet (it is sorted by descending of value column which is also required), the sum of all values is '8409131'.
ID NAME VALUE
1000000090 A 2295175
1000000974 B 1942753
1000015555 C 1887965
1000004864 D 1310400
1000015557 E 972838
If I enter 75%, the value is 65170765.25, so I need to return all the IDs which forms the '65170765', less than or equals to. So in this case below are the sum of values which are less than 65170765.
ID NAME VALUE
1000000090 A 2295175
1000000974 B 1942753
1000015555 C 1887965
Is this possible to achieve my requirement in Access SQL?
My plan is to make a running total column to find sum of first two rows and then sum of that value with next row. But in Access, I am not able to figure out how to create incremental rows in select query also to achieve this.
Query I tried:
SELECT T1.ID, T1.NAME, T1.VALUE,(T1.VALUE + T2.VALUE)
FROM (
SELECT ID , RUN_MANAGER.NAME AS NAME, RUN_MANAGER.REPORTING_PERIOD, SUM(VALUE) As VALUE
FROM DATA
INNER JOIN RUN_MANAGER
ON DATA.RUN_NUMBER=RUN_MANAGER.RUN_NUMBER
WHERE RUN_MANAGER.NAME='A'
GROUP BY ID,RUN_MANAGER.NAME
ORDER BY SUM(VALUE) DESC) AS T1
INNER JOIN (
SELECT ID , RUN_MANAGER.NAME AS NAME, RUN_MANAGER.REPORTING_PERIOD, SUM(VALUE) As VALUE
FROM DATA
INNER JOIN RUN_MANAGER
ON DATA.RUN_NUMBER=RUN_MANAGER.RUN_NUMBER
WHERE RUN_MANAGER.NAME='A'
GROUP BY ID,RUN_MANAGER.NAME
ORDER BY SUM(VALUE) DESC) AS T2
ON T1.ID=T2.ID+1
This is not a duplicate question. The problem is, this question is based on Access SQL and also I do not have any incremental ascending rows.
If you have a table like t:
ID NAME VALUE
1000000090 A 2295175
1000000974 B 1942753
1000015555 C 1887965
1000004864 D 1310400
1000015557 E 972838
You can use this query:
SELECT *
FROM t
WHERE
(SELECT SUM(VALUE) FROM t ti WHERE ti.Name <= t.Name) < (SELECT SUM(VALUE) FROM t ti) * 0.75
For this:
ID NAME VALUE
1000000090 A 2295175
1000000974 B 1942753
1000004864 D 1310400