Why Select Distinct stored 'As T' and how to alias? - sql

From this helpful response on another question on stackoverflow.com (How do I count unique items in field in Access query?), the answer contained:
SELECT Count(*) AS N
FROM
(SELECT DISTINCT Name FROM table1) AS T;
Why is the distinct selection aliased "As T" (i.e. not why the letter T, but why do this?)
If you had the case of:
SELECT Count(Long_Table_Name_Here.[Field1]) AS N
FROM
(SELECT DISTINCT Field1 FROM Long_Table_Name_Here) AS T;
How could you also alias the long table name?

Because MS Access requires that every "object" referred to in the FROM clause has a name. Tables have a default name -- which is their name. (Actually, you can use either multi-part name or just the table name.)
As for your second query:
SELECT Count(Long_Table_Name_Here.[Field1]) AS N
FROM (SELECT DISTINCT Field1 FROM Long_Table_Name_Here) AS T;
This will result in a syntax error because Long_Table_Name_Here is not defined. You need to use the table alias defined in the FROM clause:
SELECT Count(T.[Field1]) AS N
FROM (SELECT DISTINCT Field1 FROM Long_Table_Name_Here) AS T;

Related

how do i transfer a alias name from one query to another?

How do i save an alias name of one table in SQL (bigquery) to use in later queries?. there must be a way to avoid having to write the entire table name for each query. in this example ,id like to save the nameof the table as Citibike_station. how can i transfer this alias name to use in a different query?
FROM bigquery-public-data.new_york_citibike.citibike_stations` AS citibike_stations
not sure exactly what to do here. I've tired researching it online but i haven't found a satisfactory answer
ex:
"select column from table t"
From now on, you can reference "t" on your query and it will be interpreted as the table you are looking for.
"AS" should still be used for columns
For table alias visibility, you can refer to here.
FROM clause aliases are not visible to subqueries in the same FROM clause.
But if you want to use a short alias instead of fully qualified table name,
you might consider CTE (common table expression, or somtimes called as named subquery) or a temp table like below. (I don't prefer though)
WITH citibike_stations AS (
SELECT * FROM `bigquery-public-data.new_york_citibike.citibike_stations`
),
subquery_1 AS (
SELECT * FROM citibike_stations
),
subquery_2 AS (
SELECT * FROM (
SELECT 1 AS dummy
) CROSS JOIN citibike_stations
)
SELECT * FROM subquery_2 LIMIT 10;
For multiple select statements,
CREATE TEMP TABLE citibike_stations AS
SELECT * FROM `bigquery-public-data.new_york_citibike.citibike_stations`;
-- now you can use a shorthand table name instead of FQTN.
SELECT * FROM citibike_stations LIMIT 1;
SELECT * FROM (
SELECT 1 AS dummy
) CROSS JOIN citibike_stations LIMIT 1;

How can i do a recursive select from the same Table in SQL?

I have a table with the following
Table1:
ObjectName Field Type Link
Account Name String
Asset AccountId Guid Account
Asset Name String
Account BillingStreet String Details
Details FirstName String Order
Order OrderNo Integer
Order OrderItem String
The primary point of reference is Asset. what i mean by that is that I can do a select * from Table1 where ObjectName = 'Asset'. That would give me 2 rows.
But there is a Link to Asset ie Account .
So if there is a link on the select above then select all rows with that name
So something like:
select * from Asset , if there is a value in Link column then select all rows that have an ObjectName of the Link Name and keep going until there is no more. So it would finish when it selects the Order
because there is no Link on Order
If i was to do a select * from Table1 where ObjectName = 'Account', then since there is a Link in on of the rows , I would need to select Details row and in turn details has a a link to Order and I need to select Order and since Order has no Linhk , thats it
How can i do this complex query in sql, dont know where to start from ?
How can i do this complex query in sql ?
You are describing a hierarchical query. The syntax slightly varies across databases (and not all databases implement this feature), but the idea is:
with recursive cte (objectname, field, type, link) as (
select t.* from table1 t where objectname = 'Asset'
union all
select t.*
from table1 t
inner join cte c on c.link = t.objectname
)
select * from cte

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;
'

count all the distinct records in a table

I need to count all the distinct records in a table name with a single query and also without using any sub-query.
My code is
select count ( distinct *) from table_name
It gives an error:
Incorrect syntax near '*'.
I am using Microsoft SQL Server
Try this -
SELECT COUNT(*)
FROM
(SELECT DISTINCT * FROM [table_name]) A
I'm afraid that if you don't want to use a subquery, the only way to achieve that is replacing * with a concatenation of the columns in your table
select count(distinct concat(column1, column2, ..., columnN))
from table_name
To avoid undesired behaviours (like the concatenation of 1 and 31 becoming equal to the concatenation of 13 and 1) you could add a reasonable separator
select count(distinct concat(column1, '$%&£', column2, '$%&£', ..., '$%&£', columnN)
from table_name
You can use CTE.
;WITH CTE AS
(
SELECT DISTINCT * FROM TableName
)
SELECT COUNT(*)
FROM CTE
Hope this query gives you what you required.
As others mentioned, you cannot use DISTINCT with *. Also it is good practice to use a column name instead of the *, like a unique key / primary key of the table.
SELECT COUNT( DISTINCT id )
FROM table
select distinct Name , count(Name) from TableName
group by Name
having count(Name)=1
select ##rowcount
I had the same issue involving a query that had multiple joins to tables and I could not simply do count(distinct ) or count(distinct alias.).
My solution was to create a string made up of the key columns I cared about and count them.
SELECT Count(DISTINCT person.first || '~' || person.last)
from person;
If you want to use DISTINCT keyword, you need to specify column name on which bases you want to get distinct records.
Example:
SELECT count(DISTINCT Column-Name) FROM table_name

`single-row subquery returns more than one row` error unclarity

I've got two tables.
The first one hold a type and the second one the value of this type.
In my example if there are more values 'john' as 'first_name' i get:single-row subquery returns more than one row
SELECT DISTINCT id FROM name WHERE id=(
SELECT id FROM name WHERE text1='first_name' INTERSECT
SELECT name_id FROM value WHERE text2='john');
I'm not very good with sql. I should use LEFT JOIN or something like that but it's not really clear to me how i should do this.
Since subquery [can] returns multiple values, IN is better use than =
SELECT DISTINCT id
FROM name
WHERE id IN (
SELECT id FROM name WHERE text1='first_name'
INTERSECT
SELECT name_id FROM value WHERE text2='john');
IN is equivalent for OR, example:
SELECT *
FROM tableName
WHERE a = 4 or a = 5 or a = 6
can be written as
SELECT *
FROM tableName
WHERE a in (4,5,6)
The = (equal sign) is used to assign single value.
Apart from the simple fix (using IN instead of id=), you can also use a somewhat simpler version of your query:
SELECT DISTINCT id FROM name WHERE text1='first_name'
and id in (
SELECT name_id FROM value WHERE text2='john')
SELECT id FROM name WHERE text1='first_name' INTERSECT
SELECT name_id FROM value WHERE text2='john');
This query returns more than one row, then you should use IN clause like here
SELECT DISTINCT id FROM name WHERE id IN (
SELECT id FROM name WHERE text1='first_name' INTERSECT
SELECT name_id FROM value WHERE text2='john');
Or if you expect only a row, you have to review your DB's logic and behaviour.
you could just change
WHERE id=
to
WHERE id IN