Insert -> select and add my column - sql

how i can added my values in column
for example
t1
id | name | surname | mycolumn
1 | f | g |
+++|++++++|+++++++++|++++++++++
and t2
u_id | u_name | u_surname
1 | 2f | 2g
+++++|++++++++|+++++++++++
:)
so, query
INSERT INTO t1 SELECT (u_name,u_surname) FROM t2 WHERE u_id = 1
how set value mycolumn, in my variable?

If I understood your question: you are trying to insert values into a table from another table but they have different column names and different column count. In that case, you can simply rename the columns of the second table since you are querying the result, but you will need a third column, for that use NULL if you don't have a value yet
INSERT INTO t1
SELECT u_id id,u_name name,u_surname surname, null mycolumn
FROM t2 WHERE u_id = 1

Related

Insert value of one column from one table to another table based on where condition

I have one question . Suppose there is one table rules in which column department, action ,left_source and right_source,left_source_id,right_source_id is there .Another table is source table where column is name,I'd .
Now i have to insert rules to rule table but in left_source_id and right_source_id i have to insert value from source table based on I'd column . I need some immediate help .
(Source table column I'd contains all the name of left_source and right_source )
Insert Select...union all..select for example
drop table if exists t,t1;
create table t(id int,leftsource varchar(1),rightsource varchar(1));
create table t1(id int,val varchar(1));
insert into t1 values
(1,'l'),(2,'r');
insert into t
select id,val,null from t1 where id = 1
union all
select id,null,val from t1 where id = 2
select * from t;
+------+------------+-------------+
| id | leftsource | rightsource |
+------+------------+-------------+
| 1 | l | NULL |
| 2 | NULL | r |
+------+------------+-------------+
2 rows in set (0.001 sec)

SQLite query - filter name where each associated id is contained within a set of ids

I'm trying to work out a query that will find me all of the distinct Names whose LocationIDs are in a given set of ids. The catch is if any of the LocationIDs associated with a distinct Name are not in the set, then the Name should not be in the results.
Say I have the following table:
ID | LocationID | ... | Name
-----------------------------
1 | 1 | ... | A
2 | 1 | ... | B
3 | 2 | ... | B
I'm needing a query similar to
SELECT DISTINCT Name FROM table WHERE LocationID IN (1, 2);
The problem with the above is it's just checking if the LocationID is 1 OR 2, this would return the following:
A
B
But what I need it to return is
B
Since B is the only Name where both of its LocationIDs are in the set (1, 2)
You can try to write two subquery.
get count by each Name
get count by your condition.
then join them by count amount, which means your need to all match your condition count number.
Schema (SQLite v3.17)
CREATE TABLE T(
ID int,
LocationID int,
Name varchar(5)
);
INSERT INTO T VALUES (1, 1,'A');
INSERT INTO T VALUES (2, 1,'B');
INSERT INTO T VALUES (3, 2,'B');
Query #1
SELECT t2.Name
FROM
(
SELECT COUNT(DISTINCT LocationID) cnt
FROM T
WHERE LocationID IN (1, 2)
) t1
JOIN
(
SELECT COUNT(DISTINCT LocationID) cnt,Name
FROM T
WHERE LocationID IN (1, 2)
GROUP BY Name
) t2 on t1.cnt = t2.cnt;
| Name |
| ---- |
| B |
View on DB Fiddle
You can just use aggregation. Assuming no duplicates in your table:
SELECT Name
FROM table
WHERE LocationID IN (1, 2)
GROUP BY Name
HAVING COUNT(*) = 2;
If Name/LocationID pairs can be duplicated, use HAVING COUNT(DISTINCT LocationID) = 2.

PostgreSQL Get all rows where its id is not anywhere in another column for a table

--------------+-------------------+
id | parent_id |
--------------+-------------------|
18 | <null> |
20 | <null> |
25 | 18 |
--------------+-------------------+
I want my query to select all ids where its id doesn't exist in parent_id column. How would I go about doing that?
Easiest way is to do use NOT EXISTS to return those id's not found in the parent_id column:
select id
from tablename t1
where not exists (select 1 from tablename t2
where t2.parent_id = t1.id)
NOT IN may also be used, but be careful, NULL's have to be taken care of:
select id
from tablename
where id not in (select parent_id from tablename
where parent_id is not null)

How do I get LIKE and COUNT to return the number of rows less than a value not in the row?

For example:
SELECT COUNT(ID) FROM My_Table
WHERE ID <
(SELECT ID FROM My_Table
WHERE ID LIKE '%4'
ORDER BY ID LIMIT 1)
My_Table:
X ID Y
------------------------
| | A1 | |
------------------------
| | B2 | |
------------------------
| | C3 | |
------------------------ -----Page 1
| | D3 | |
------------------------
| | E3 | |
------------------------
| | F5 | |
------------------------ -----Page 2
| | G5 | |
------------------------
| | F6 | |
------------------------
| | G7 | | -----Page 3
There is no data ending in 4 but there still are 5 rows that end in something less than "%4".
However, in this case were there is no match, so SQLite only returns 0
I get it is not there but how do I change this behavior to still return number of rows before it, as if it was there?
Any suggestions?
Thank You.
SELECT COUNT(ID) FROM My_Table
WHERE ID < (SELECT ID FROM My_Table
WHERE SUBSTRING(ID, 2) >= 4
ORDER BY ID LIMIT 1)
Assuming there is always one letter before the number part of the id field, you may want to try the following:
SELECT COUNT(*) FROM my_table WHERE CAST(substr(id, 2) as int) <= 4;
Test case:
CREATE TABLE my_table (id char(2));
INSERT INTO my_table VALUES ('A1');
INSERT INTO my_table VALUES ('B2');
INSERT INTO my_table VALUES ('C3');
INSERT INTO my_table VALUES ('D3');
INSERT INTO my_table VALUES ('E3');
INSERT INTO my_table VALUES ('F5');
INSERT INTO my_table VALUES ('G5');
INSERT INTO my_table VALUES ('F6');
INSERT INTO my_table VALUES ('G7');
Result:
5
UPDATE: Further to the comment below, you may want to consider using the ltrim() function:
The ltrim(X,Y) function returns a string formed by removing any and all characters that appear in Y from the left side of X.
Example:
SELECT COUNT(*)
FROM my_table
WHERE CAST(ltrim(id, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') as int) <= 4;
Test case (adding to the above):
INSERT INTO my_table VALUES ('ABC1');
INSERT INTO my_table VALUES ('ZWY2');
New Result:
7
In MySQL that would be:
SELECT COUNT(ID)
FROM My_Table
WHERE ID <
(
SELECT id
FROM (
SELECT ID
FROM My_Table
WHERE ID LIKE '%4'
ORDER BY
ID
LIMIT 1
) q
UNION ALL
SELECT MAX(id)
FROM mytable
LIMIT 1
)

Selecting unique rows in a set of two possibilities

The problem itself is simple, but I can't figure out a solution that does it in one query, and here's my "abstraction" of the problem to allow for a simpler explanation:
I will let my original explenation stand, but here's a set of sample data and the result i expect:
Ok, so here's some sample data, i separated pairs by a blank line
-------------
| Key | Col | (Together they from a Unique Pair)
--------------
| 1 Foo |
| 1 Bar |
| |
| 2 Foo |
| |
| 3 Bar |
| |
| 4 Foo |
| 4 Bar |
--------------
And the result I would expect, after running the query once, it need to be able to select this result set in one query:
1 - Foo
2 - Foo
3 - Bar
4 - Foo
Original explenation:
I have a table, call it TABLE where I have a two columns say ID and NAME which together form the primary key of the table. Now I want to select something where ID=1 and then first checks if it can find a row where NAME has the value "John", if "John" does not exist it should look for a row where NAME is "Bruce" - but only return "John" if both "Bruce" and "John" exists or only "John" exists of course.
Also note that it should be able to return several rows per query that match the above criteria but with different ID/Name-combinations of course, and that the above explanation is just a simplification of the real problem.
I could be completely blinded by my own code and line of thought but I just can't figure this out.
This is fairly similar to what you wrote, but should be fairly speedy as NOT EXISTS is more efficient, in this case, than NOT IN...
mysql> select * from foo;
+----+-----+
| id | col |
+----+-----+
| 1 | Bar |
| 1 | Foo |
| 2 | Foo |
| 3 | Bar |
| 4 | Bar |
| 4 | Foo |
+----+-----+
SELECT id
, col
FROM foo f1
WHERE col = 'Foo'
OR ( col = 'Bar' AND NOT EXISTS( SELECT *
FROM foo f2
WHERE f1.id = f2.id
AND f2.col = 'Foo'
)
);
+----+-----+
| id | col |
+----+-----+
| 1 | Foo |
| 2 | Foo |
| 3 | Bar |
| 4 | Foo |
+----+-----+
You can join the initial table to itself with an OUTER JOIN like this:
create table #mytest
(
id int,
Name varchar(20)
);
go
insert into #mytest values (1,'Foo');
insert into #mytest values (1,'Bar');
insert into #mytest values (2,'Foo');
insert into #mytest values (3,'Bar');
insert into #mytest values (4,'Foo');
insert into #mytest values (4,'Bar');
go
select distinct
sc.id,
isnull(fc.Name, sc.Name) sel_name
from
#mytest sc
LEFT OUTER JOIN #mytest fc
on (fc.id = sc.id
and fc.Name = 'Foo')
like that.
No need to make this overly complex, you can just use MAX() and group by ...
select id, max(col) from foo group by id
try this:
select top 1 * from (
SELECT 1 as num, * FROM TABLE WHERE ID = 1 AND NAME = 'John'
union
SELECT 2 as num, * FROM TABLE WHERE ID = 1 AND NAME = 'Bruce'
) t
order by num
I came up with a solution myself, but it's kind of complex and slow - nor does it expand well to more advanced queries:
SELECT *
FROM users
WHERE name = "bruce"
OR (
name = "john"
AND NOT id
IN (
SELECT id
FROM posts
WHERE name = "bruce"
)
)
No alternatives without heavy joins, etc. ?
Ok, so here's some sample data, i separated pairs by a blank line
-------------
| Key | Col | (Together they from a Unique Pair)
--------------
| 1 Foo |
| 1 Bar |
| |
| 2 Foo |
| |
| 3 Bar |
| |
| 4 Foo |
| 4 Bar |
--------------
And the result I would expect:
1 - Foo
2 - Foo
3 - Bar
4 - Foo
I did solve it above, but that query is horribly inefficient for lager tables, any other way?
Here's an example that works in SQL Server 2005 and later. It's a useful pattern where you want to choose the top row (or top n rows) based on a custom ordering. This will let you not just choose among two values with custom priorities, but any number. You can use the ROW_NUMBER() function and a CASE expression:
CREATE TABLE T (id int, col varchar(10));
INSERT T VALUES (1, 'Foo')
INSERT T VALUES (1, 'Bar')
INSERT T VALUES (2, 'Foo')
INSERT T VALUES (3, 'Bar')
INSERT T VALUES (4, 'Foo')
INSERT T VALUES (4, 'Bar')
SELECT id,col
FROM
(SELECT id, col,
ROW_NUMBER() OVER (
PARTITION BY id
ORDER BY
CASE col
WHEN 'Foo' THEN 1
WHEN 'Bar' THEN 2
ELSE 3 END
) AS RowNum
FROM T
) AS X
WHERE RowNum = 1
ORDER BY id
In PostgreSQL, I believe it would be this:
SELECT DISTINCT ON (id) id, name
FROM mytable
ORDER BY id, name = 'John' DESC;
Update - false sorts before true - I had it backwards originally. Note that DISTINCT ON is a PostgreSQL feature and not part of standard SQL. What happens here is that it only shows you the first row for any given id that it comes across. Since we order by weather the name is John, rows named John will be selected over all other names.
With your second example, it would be:
SELECT DISTINCT ON (key) key, col
FROM mytable
ORDER BY key, col = 'Foo' DESC;
This will give you:
1 - Foo
2 - Foo
3 - Bar
4 - Foo
You can use joins instead of the exists and this may improve the query plan in cases where the optimizer is not smart enough:
SELECT f1.id
,f1.col
FROM foo f1
LEFT JOIN foo f2
ON f1.id = f2.id
AND f2.col = 'Foo'
WHERE f1.col = 'Foo'
OR ( f1.col = 'Bar' AND f2.id IS NULL )