PostgreSQL: column does not exist when searched in WHERE clause - sql

So, I have this little SQL query:
SELECT
COUNT( distinct (customerid)) AS cs, prod_id
FROM
(orderlines JOIN orders ON (orderlines.orderid=orders.orderid)) AS table_1
WHERE table_1.cs= 1
GROUP BY table_1.prod_id
ORDER BY cs ASC
What this is supposed to do, is count the distinct customerid's and return a table containing only the entries where there was only distinct customerid.
When I execute this I get the following error:
ERROR: column table_1.cs does not exist
LINE 6: WHERE table_1.cs= 1
^
*********Error**********
ERROR: column table_1.cs does not exist
SQL state: 42703
Character: 156
It claims that the column cs does not exist when I have clearly defined it here:
SELECT
COUNT( distinct (customerid)) AS cs, prod_id

You can't reference in a WHERE clause an alias defined in the Selection list. You can either use an HAVING clause or use a sub select ..
With a sub select you can arrange something like this :
SELECT * FROM (
SELECT
COUNT( distinct (customerid)) AS cs, prod_id
FROM
(orderlines JOIN orders ON (orderlines.orderid=orders.orderid))
GROUP BY table_1.prod_id) AS table_1
WHERE cs= 1
ORDER BY cs ASC

Related

PostgreSQL create count, count distinct columns

fairly new to PostgreSQL and trying out a few count queries. I'm looking to count and count distinct all values in a table. Pretty straightforward -
CountD Count
351 400
With a query like this:
SELECT COUNT(*)
COUNT(id) AS count_id,
COUNT DISTINCT(id) AS count_d_id
FROM table
I see that I can create a single column this way:
SELECT COUNT(*) FROM (SELECT DISTINCT id FROM table) AS count_d_id
But the title (count_d_id) doesn't come through properly and unsure how can I add an additional column. Guidance appreciated
This is the correct syntax:
SELECT COUNT(id) AS count_id,
COUNT(DISTINCT id) AS count_d_id
FROM table
Your original query aliases the subquery rather than the column. You seem to want:
SELECT COUNT(*) AS count_d_id FROM (SELECT DISTINCT id FROM table) t
-- column alias --^ -- subquery alias --^

I can't figure out how to do this DISTINCT

Good morning
I tried and tried to understand why this Query gives the usual error on Group By. I would like to find the duplicate lines and delete them. I found this query on Microsoft's MSDN but despite this it keeps giving me this error on Group By.
The main table has 3 fields "Id, Item, Description", the table name is "tlbDescription", this query should in theory create a table named "duplicate_table" insert the duplicate values inside the "duplicate_table", then delete the values from table "tlbDescription" and finally delete the table "duplicate_table".
If someone can kindly give me a hand
Thank you
Fabrizio
This is the query:
SELECT DISTINCT *
INTO duplicate_table
FROM [tlbDescrizione]
GROUP BY [Articolo]
HAVING COUNT([Articolo]) > 1
DELETE [tlbDescrizione]
WHERE [Articolo] IN (SELECT [Articolo] FROM duplicate_table)
INSERT [tlbDescrizione]
SELECT * FROM duplicate_table
DROP TABLE duplicate_table
This query doesn't make sense:
SELECT DISTINCT *
INTO duplicate_table
FROM [tlbDescrizione]
GROUP BY [Articolo]
HAVING COUNT([Articolo]) > 1;
It is selecting all columns but is an aggregation query because of the GROUP BY. Hence, the SELECT columns are inconsistent with the GROUP BY columns and you get an error.
If you want all the columns then you can use window functions:
SELECT DISTINCT *
INTO duplicate_table
FROM (SELECT d.*, COUNT(*) OVER (PARTITION BY d.Articolo) as cnt
FROM tlbDescrizione d
) d
WHERE cnt > 1;
Or, if you want only the ids:
SELECT Articolo
INTO duplicate_table
FROM tlbDescrizione
GROUP BY [Articolo]
HAVING COUNT(*) > 1;

SQL Server - Select multiple Columns Group By 1 Column

I have looked at many examples of selecting many columns but only grouping by 1 column and mine seem to give me duplicate results. See below I would like to select all the columns in my table but would like to only GROUP BY VehicleId. On the screenshot you'll see that the results are actually not grouped by VehicleId.
Any idea on what I am doing wrong?
Try 1:
SELECT
h.*,
TotalFines = 1,
TotalIncidents = 1,
TotalVehicleAllocations = 1,
TotalVehicleConditions = 1,
TotalMileageApplications = 1
FROM
(
SELECT h1.VehicleId FROM [dbo].[VehicleHistory] h1 GROUP BY h1.VehicleId
) GroupedList
INNER JOIN [dbo].[VehicleHistory] h ON GroupedList.VehicleId=h.VehicleId
ORDER BY
h.VehicleId;
Try 2:
SELECT t1.* FROM VehicleHistory t1
INNER JOIN
(
SELECT VehicleId FROM VehicleHistory GROUP BY VehicleId
) t2
ON t1.VehicleId=t2.VehicleId
Both queries produce the same results with duplicate rows for each VehicleId as per below:
Here's my expected results below. The results are a query produced by Entity Framework. But I would like to rewrite the linq query into T-SQL:
This is because you are gtouping in subquery (which would be same as SELECT DISTINCT h1.VehicleId FROM [dbo].[VehicleHistory] h1):
SELECT h1.VehicleId FROM [dbo].[VehicleHistory] h1 GROUP BY h1.VehicleId
and then you are joining in on that column, which can cause duplicates to occur (you have duplicate IDs in VehicleHistory).
All you need to do is:
SELECT VehicleId,
MAX(DateUpdated) DateUpdated, --or other aggregate function
--rest of your columns in appropriate aggreagte functions
FROM VehicleHistory
GROUP BY VehicleId

incorrect syntax near ';'

In SQL Server 2016 I miss this error in this query:
select count(*)
from (select count(*), clave
from products
where state = 1
group by key
having count(*) > 1 );
I have tried to copy and paste the query in a note pad in case some invalid character or space has been inserted.
You need alias :
select count(*)
from (select count(*)
from products
where [state] = 1
group by [key]
having count(*) > 1
) t; -- t alias
Considering to use only words or identifiers which have not reserved by SQL Server, such as key (especially in your case) & many more.
Second thing when you include group by clause with your query you should be care about select statement with expressions/columns (which are available in group by clause or the expression/column which are not in group by clause you should include aggregate function to that column/expression.)
'Key' is a reserve word so you can not use it so you should rename it and your result is a table so you should give it an alias.
Try something like
`
select count(*)
from (select count(*), clave
from products
where state = 1
group by key1
having count(*) > 1 ) AS product_alias;
'

Create a UNION query that identifies which table the unique data came from

I have two tables with data. Both tables have a CUSTOMER_ID column (which is numeric). I am trying to get a list of all the unique values for CUSTOMER_ID and know whether or not the CUSTOMER_ID exists in both tables or just one (and which one).
I can easily get a list of the unique CUSTOMER_ID:
SELECT tblOne.CUSTOMER_ID
FROM tblOne.CUSTOMER_ID
UNION
SELECT tblTwo.CUSTOMER_ID
FROM tblTwo.CUSTOMER_ID
I can't do just add an identifier column to the SELECT statemtn (like: SELECT tblOne.CUSTOMER_ID, "Table1" AS DataSource) because then the records wouldn't be unique and it will get both sets of data.
I feel I need to add it somewhere else in this query but am not sure how.
Edit for clarity:
For the union query output I need an additional column that can tell me if the unique value I am seeing exists in: (1) both tables, (2) table one, or (3) table two.
If the CUSTOMER_ID appears in both tables then we'll have to arbitrarily pick which table to call the source. The following query uses "tblOne" as the [SourceTable] in that case:
SELECT
CUSTOMER_ID,
MIN(Source) AS SourceTable,
COUNT(*) AS TableCount
FROM
(
SELECT DISTINCT
CUSTOMER_ID,
"tblOne" AS Source
FROM tblOne
UNION ALL
SELECT DISTINCT
CUSTOMER_ID,
"tblTwo" AS Source
FROM tblTwo
)
GROUP BY CUSTOMER_ID
Gord Thompson's answer is correct. But, it is not necessary to do a distinct in the subqueries. And, you can return a single column with the information you are looking for:
select customer_id,
iif(min(which) = max(which), min(which), "both") as DataSource
from (select customer_id, "tblone" as which
from tblOne
UNION ALL
select customer_id, "tbltwo" as which
from tblTwo
) t
group by customer_id
We could add an identifier column with the integer data type and then do an outer query:
SELECT
CUSTOMER_ID,
sum(Table)
FROM
(
SELECT
DISTINCT CUSTOMER_ID,
1 AS Table
FROM tblOne
UNION
SELECT
DISTINCT CUSTOMER_ID,
2 AS Table
FROM tblTwo
)
GROUP BY CUSTOMER_ID`
So if the "sum is 1" then it comes from tablOne and if it is 2 then it comes from tableTwo an if it is 3 then it exists in both
If you want to add a 3rd table in the union then give it a value of 4 so that you should have a unique sum for each combination