I have a list of ids and need to check whether user with id is in DB or not in one SELECT. Like SELECT WHERE IN (). But SELECT WHERE IN () doesn't suit my needs, I need in one SELECT distinguish those ids that are in table, and those that are not, not using any loops like multiple SELECTS. Any ideas are welcome!
I'm not sure if this is what you need, but I guess you have table 1 which contains a lot of IDs, and you would like to see which ones occur in table 2 and which ones don't?
select T1.ID, count(*) 'Times of occurrences in T2'
from table 1 T1
left outer join table 2 T2
ON T1.ID = T2.ID
group by T1.ID
You should provide more details. Would it be a single query so a list could be hardcoded into query or you want to find general solution for any list of ids provided? How long is your list?
For single query and not very long list you can use union. On example:
SELECT some_value, EXISTS( SELECT 1 FROM tableName WHERE user_id = some_value )
UNION ALL
SELECT other_value, EXISTS( SELECT 1 FROM tableName WHERE user_id = other_value )
UNION ALL
SELECT other_value2, EXISTS( SELECT 1 FROM tableName WHERE user_id = other_value2 )
UNION ALL
.....
If your list of ids can vary and/or consists of thousands of records it is impossible. In list you have columnar layout and you want to change it to row-level results. In MsSQL there are PIVOT, UNPIVOT clauses which can do that. In MySQL such transformation without explicit unions are impossible.
Related
Please suggest how to insert new record between two records.
Id 3 of record/row is missed between id 2 and 4 in sql table.
SQL tables are unordered sets. You cannot add a record "between two records", because there is no order to the records. Even if your queries seem to return the rows in some order, it's completely arbitrary, and unless you have an explicit order by clause could very well change.
In other words - you should just insert the new row, and if you care about ordering by the id, always use order by id in your queries.
You could use a calendar table based approach here:
INSERT INTO yourTable (id)
SELECT t1.id
FROM
(
SELECT 1 AS id UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
SELECT 4 UNION ALL SELECT 5
) t1
LEFT JOIN yourTable t2
ON t2.id = t1.id
WHERE
t1.id IS NULL;
In practice, you might replace the inlined subquery aliased as t1 above with a bona fide sequence table covering all id values which you would want to cover.
How can I create a query to SELECT ALL DB WITHOUT duplicates
Like (old DB that is no longer in use c,f,g. basically if it does have eur and has an original name than it is relevant):
a
b
c
ceur
d
f
feur
g
geur
I need it to be like:
a
b
ceur
d
feur
geur
Many thanks...
SELECT DISTINCT
is what you're looking for. See more here.
For instance, let's say you have a table that contains the following rows:
name, city, address, country.
You now wish to get the countries that has been stored, without duplicates. Multiple people might come from the same country, and so the table would most likely have duplicate entries of that country.
How you achieve this is by using the SELECT DISTINCT.
Example:
SELECT DISTINCT country FROM table_name;
What this will do is retreive the country row without duplicates. That way, you can see which countries are actually stored in that table without duplicates.
If you have multiple databases (I don't know if that's what you were getting at), then you will need to perform a JOIN on the relevant tables, given you have access to them all. I would recommend doing a LEFT JOIN if you are to join more than just 1 extra table.
Example:
SELECT DISTINCT table_name.row_name, table_name.row_name2, table_name.row_name3
FROM table_name
LEFT JOIN table_name2 ON table_name.row_name = table_name2.row_name
LEFT JOIN table_name3 ON table_name2.row_name = table_name3.row_name
[...]
WHERE table.row_name = 'value';
Can you query information_schema.TABLES and distinct in the select, plus a predicate to filter out whatever you don't want?
You can do:
select t.*
from t
where name like '%eur'
union all
select t.*
from t
where not like '%eur' and
not exists (select 1 from t t2 where t2.name = concat(t.name, 'eur');
I am not sure if this is possible. But is it possible to do a join on 2 tables, but return the data for only one of the tables. I want to join the two tables based on a condition, but I only want the data for one of the tables. Is this possible with SQL, if so how? After reading the docs, it seems that when you do a join you get the data for both tables. Thanks for any help!
You get data from both tables because join is based on "Cartesian Product" + "Selection". But after the join, you can do a "Projection" with desired columns.
SQL has an easy syntax for this:
Select t1.* --taking data just from one table
from one_table t1
inner join other_table t2
on t1.pk = t2.fk
You can chose the table through the alias: t1.* or t2.*. The symbol * means "all fields".
Also you can include where clause, order by or other join types like outer join or cross join.
A typical SQL query has multiple clauses.
The SELECT clause mentions the columns you want in your result set.
The FROM clause, which includes JOIN operations, mentions the tables from which you want to retrieve those columns.
The WHERE clause filters the result set.
The ORDER BY clause specifies the order in which the rows in your result set are presented.
There are a few other clauses like GROUP BY and LIMIT. You can read about those.
To do what you ask, select the columns you want, then mention the tables you want. Something like this.
SELECT t1.id, t1.name, t1.address
FROM t1
JOIN t2 ON t2.t1_id = t1.id
This gives you data from t1 from rows that match t2.
Pro tip: Avoid the use of SELECT *. Instead, mention the columns you want.
This would typically be done using exists (or in) if you prefer:
select t1.*
from table1 t1
where exists (select 1 from table2 t2 on t2.x = t1.y);
Although you can use join, it runs the risk of multiplying the number of rows in the result set -- if there are duplicate matches in table2. There is no danger of such duplicates using exists (or in). I also find the logic to be more natural.
If you join on 2 tables.
You can use SELECT to select the data you want
If you want to get a table of data, you can do this,just select one table date
SELECT b.title
FROM blog b
JOIN type t ON b.type_id=t.id;
If you want to get the data from two tables, you can do this,select two table date.
SELECT b.title,t.type_name
FROM blog b
JOIN type t ON b.type_id=t.id;
I am looking to run this query on a list of tables.
SELECT Description,Code,count(*) as count
FROM table1
group by Description,code
having count(*) > 1
I will have to run this query on 30+ different tables, I was wondering If I could change the from statement and just list off the table names.
In addition, is there some functionality that will add the name of the table that it came from in a seperate column to distinguish where the results came from?
Thanks in advance
You might use UNION ALL to put it together. Unless you need some dynamic table selection.
SELECT Description,Code,count(*) as count, 'table1' as tableNane
FROM table1
group by Description,code
having count(*) > 1
UNION ALL
SELECT Description,Code,count(*) as count, 'table2' as tableNane
FROM table2
group by Description,code
having count(*) > 1
...
Actualy I like #Shubhradeep Majumdar version. It will generate more concise code.
SELECT Description,Code, Count(Code), tableName FROM (
SELECT Description,Code, 'table1' as tableName
FROM table1
UNION ALL
SELECT Description,Code, 'table2' as tableName
FROM table2
) tables
GROUP BY tableName, Description, Code
HAVING COUNT(Code) > 1
But there might be a little catch to it. It is more elegant code, but it might actually be slower than first version. The problem is that tableName is appended at every record before grouping while in my first version you do that on already processed data.
Carrying over from #Marek's answer, You could first append all the tables to a table with union all.
select *, 'tab1' as tabnm from tab1
union all
select *, 'tab2' as tabnm from tab2
union all
select *, 'tab3' as tabnm from tab3
-- and so on...
And then use your code to process that final table.
will save you a great deal of time.
EDITED with a column specifying the table name
I have a series of tables that contain data of similar format. I.e. a UNION would work.
Conceptually you can think of it as 1 table partitioned into multiple tables.
I want to get the data from all of these tables sorted.
Now the problem I have is that the data are too much to be displayed all at once to the user, so I need to display them in portions i.e. pages.
Now my problem is that I need to display the data sorted (as already said).
So if I do something like:
SELECT FROM TABLE_1
UNION
SELECT FROM TABLE_2
UNION
....
SELECT FROM TABLE_N
ORDER BY COL
LIMIT OFFSET, RECORDS;
I would constantly be doing a UNION and ORDER BY to get e.g. the just the corresponding 50 records of the pages on each request.
So how would I most efficiently handle this?
My first attempt would be UNION'ing just a small number of records from each table:
( SELECT FROM table_1 ORDER BY col LIMIT #offset, #records )
UNION
...
( SELECT FROM table_N ORDER BY col LIMIT #offset, #records )
ORDER BY col LIMIT #offset, #records
If the above proves insufficient, I would build a manual index table (based on David Starkey's clever suggestion).
CREATE TABLE index_table (
table_id INT,
item_id INT,
col DATETIME,
INDEX (col, table_id, id)
);
Then populate index_table with a method of your liking (cron job, triggers on tables table_n, ...). Your SELECT statement would then look like this:
SELECT *
FROM ( SELECT * FROM index_table ORDER BY col LIMIT #offset, #records ) AS idx
LEFT JOIN table_1 ON (idx.table_id = 1 AND idx.item_id = table_1.id)
...
LEFT JOIN table_n ON (idx.table_id = n AND idx.item_id = table_n.id)
However, I am not sure of how such a query would perform with so many LEFT JOIN's. It really depends on how many tables table_n there are.
Finally, I would consider merging all tables into one single table.