table a
_______________________________
id col1 col2 col3 ...........col20
1 ............................
2 ............................
3 ............................
table b
_______________________________
id colA colB colC colD ...... colZ
query
________________________________
select a.*, b.* from a left join b on b.id = a.col20 where a.id = 1;
In this query table a and b has same column name.
And I need both of them.
select a.id as a_id .. b.id as b_id .. from a left join b on b.id = a.col20 where a.id = 1;
How to avoid typing all column name?
As far as I know there is not an easy way to select * and exclude columns, and it requires putting the full column list, but I'm sure there are other possibilities.
One way of doing this which would make those a.*, b.* type queries work, but requires some initial setup, is to create a view for the table which aliases all of the columns.
the view of a would be a select query with all of the column names aliased.
create view aview as
select id as a_id,
col1 as a_col1,
col2 as a_col2,
...
...
from a
Then anywhere else you could do something like this:
select a.*, b.*
from aview a
left join bview b on b.b_id = a.a_col20
where a.a_id = 1
If the example were that simple and you really only had 2 tables, it would be sufficient to just make a view for one of them.
Hackish, maybe.. I'd probably look to permanently change the column names on the base tables.
Related
Table A
a_id
a_name
1
apples
2
bananas
3
cherries
4
oranges
Table B
b_id
b_name
1
Hot
2
Cold
Table C
c_id
a_id
b_id
1
1
2
2
2
1
3
3
2
4
4
1
5
4
2
I am trying to get resulting table, which should show "a_name" and "b_name" with the following condition: where a_name like '%r%' and b_name like '%o%'.
Problem is that they should be found within the same row in "Table_C".
I've tried various methods of joining tables but I'm unable to get the desired result.
Here's my best coding attempt at this problem:
SELECT a.a_name,
b.b_name
FROM Table_A a
WHERE a.a_name LIKE '%r%' IN (SELECT a.a_id
FROM Table_c
WHERE b_id LIKE '%o');
Any help would be much appreciated.
The problem with your query is that you're trying to extract values of "Table B" by using a filtering operation (WHERE clause). As long as the filtering clause "just filters" - reduces the number of rows of your table - , you can't access "b.b_name" inside your SELECT clause if the FROM contains only "Table A".
In this case you may want to use two JOIN operations in place of WHERE .. IN .. construct. The main table is "Table C" because it connects "Table A" and "Table B" together. Since you have two conditions to be applied on the names, in order to make this more efficient, you can filter on the two tables ("Table A" and "Table B") before applying the JOIN operation. In this way the DBMS will apply the matching on less rows.
SELECT A.a_name,
B.b_name
FROM tabC C
INNER JOIN (SELECT * FROM tabA WHERE a_name LIKE '%r%') A
ON C.a_id = A.a_id
INNER JOIN (SELECT * FROM tabB WHERE b_name LIKE '%o%') B
ON C.b_id = B.b_id
Check the demo here.
select
A.a_name,
B.b_name
from TableA A
inner join TableC C on C.a_id = A.a_id
inner join tableB B on B.b_id = C.b_id
where A.a_name like '%r%' and B.b_name like '%o%';
The inner join 'glues' the table together on the condition specified after the ON
The where clause is a copy provided by you. I Just added the table aliases for clarity.
Try below code:
select tableA.a_name, tableB.b_name
from tableC
left join tableA on tableA.a_id=tableC.a_id
left join tableB on tableB.b_id=tableC.b_id
where tableA.a_name like '%r%' and tableB.b_name like '%o%'
here is some sample data:
ID Item
1 A
1 A
1 B
2 A
2 A
3 A
3 A
3 A
Question: Im trying to write code so that the only records that are selected are those of customer with ID 1 (ie a customer that has both product A and B). So results should look like this:
1 A
1 A
1 B
I've tried a lot of different things, but I am stuck. I tried self-join, but it doesnt produce what I want:
SELECT a.id, a.item
FROM table1 a Join table1 b on a.id=b.id
WHERE upper(a.item) = 'A'
AND upper(b.item) = 'B';
This will give me the right customer (ie customer 1) but it doesnt pull all 3 records. It just gives 1 row.
the closest similar question is
enter link description here
since you want to see which users match a certain condition and the fetch everything about those users - you need a nested query:
SELECT id,item FROM table1 WHERE id IN(
SELECT a.id
FROM table1 a Join table1 b on a.id=b.id
WHERE upper(a.item) = 'A'
AND upper(b.item) = 'B'
)
I took your working query, and used it in a WHERE clause for a more generic query - should do the trick for you
You could use your query as subselect to get the pid and then output all the pids rows. Like this:
SELECT id, item
FROM table1
WHERE id IN (SELECT a.id
FROM table1 a
JOIN table1 b
ON a.id=b.id
WHERE UPPER(a.item) = 'A'
AND UPPER(b.item) = 'B')
is it this what you are looking for? or may be I didn't understand your question.
SELECT a.pid, a.mname
FROM meds a
WHERE a.pid = 1
I am building a SQL query which compares two tables A and B by a [name] column and returns the names from table A that are not in table B
Example
Table A
ID Name Address
1 A ABC
2 B XYZ
3 C PQR
Table B
ID Name Gender
1 A F
2 B M
3 D F
The query I wrote should return third row from table A as it is not in table B and should exclude all other rows
Following is the query I built
Select * from A oa left join B gp ON oa.name!=gp.name
the above doesn't return the results I was expecting.
Can this be corrected?
Easiest way:
select * from A where name not in (select name from B)
Better way:
select * from A where not exists (select 1 from B where B.name = A.name)
"A left join B" means keeping everything in A, and associating records in B if the condition is satisfied.
In your case, if you really wanna use left join, here is what it should be ('=', not '!='):
Select * from A oa left join B gp ON oa.name=gp.name where gp.name is null
Better way would be using 'not exists' performance-wise, or 'except' if null values are not an issue.
Using excpet operator will help
select * from TableA
except
select * from TableB
SELECT a.*
FROM A a
LEFT JOIN B b
ON a.name = b.name
WHERE b.name IS NULL
What's wrong with my sql query? I am trying to use a Join and at the same time a UNION to get all table from another table while joining other tables together based on a relationship ..
However I get the following error:
"The used SELECT statements have a different number of columns"
My query:
SELECT a.ESN, a.UnixTime, a.Payload, a.Timestamp
,b.AlarmingStatus
,b.STxModel
,c.GroupID
FROM STxMessage a
JOIN STx b ON b.ESN = a.ESN
JOIN GroupInfo c ON b.GroupID = c.GroupID
WHERE b.STxModel = 190
AND a.AlarmsChecked="y"
AND c.AlertsMasterSwitch="on"
UNION ALL
SELECT d.ESN , d.UnixTime, d.Payload, d.Timestamp FROM STxMessageArchive d
The error message says it all.
When using UNION, the columns return by the combined SELECT statement must be the same, eg.
SELECT col1, col2, col3 FROM table1
UNION
SELECT col1, col2, col3 FROM table2
if the columns do not match, you can still combine it provided that you have to provide dummy data for the column, eg
SELECT col1, col2, col3 FROM table1
UNION
SELECT col1, col2, '' AS col3 FROM table2
so in your query, it should look like this
SELECT a.ESN, a.UnixTime, a.Payload, a.Timestamp ,
b.AlarmingStatus, b.STxModel, c.GroupID
FROM STxMessage a
INNER JOIN STx b
ON b.ESN = a.ESN
INNER JOIN GroupInfo c
ON b.GroupID = c.GroupID
WHERE b.STxModel = 190 AND
a.AlarmsChecked="y" AND
c.AlertsMasterSwitch="on"
UNION ALL
SELECT d.ESN, d.UnixTime, d.Payload, d.Timestamp,
NULL AS AlarmingStatus, NULL AS STxModel, NULL AS GroupID
FROM STxMessageArchive d
hi this are the extra columns in your first query
,b.AlarmingStatus
,b.STxModel
,c.GroupID
you need this same columns in second query to do union or you need to remove this column to do union operation
Your first query is selecting 7 columns where as the second query is only selecting 4. You need to make sure the second query is selecting the same number of columns as the first to make the Union All work.
SELECT a.ESN, a.UnixTime, a.Payload, a.Timestamp
,b.AlarmingStatus
,b.STxModel
,c.GroupID
FROM STxMessage a
JOIN STx b ON b.ESN = a.ESN
JOIN GroupInfo c ON b.GroupID = c.GroupID
WHERE b.STxModel = 190
AND a.AlarmsChecked="y"
AND c.AlertsMasterSwitch="on"
UNION ALL
SELECT d.ESN , d.UnixTime, d.Payload, d.Timestamp, 'null' as AlarmingStatus,
'null' as STxModel, 'null' as GroupID FROM STxMessageArchive d
As the error says, the first part has 7 columns, and the second part has only 4. An unions needs to have the same columns on both sides. Either remove
b.AlarmingStatus ,b.STxModel ,c.GroupID
from the first part, or add (even bogus) columns in the second part.
I've seen people recommending cross joining a table on itself by doing this:
SELECT *
FROM tbl AS A, tbl AS B
WHERE A.col1 = 1 AND B.col1 = 1
But here, the engine needs to iterate through all of the rows in tbl twice to match the two queries to the results of A and B, despite the fact that the queries (and therefore the results) are the same.
Assuming that the WHERE on A and B will always be the identical for the two, this is a waste. Is there any way to query for something once, and then cross join the result of that query on itself? I'd like to avoid temp tables, which would require disk writing instead of performing this entire thing in RAM.
I am using MySQL, although any SQL answer would help a lot.
EXAMPLE:
Suppose that tbl looks as follows:
COL1 COL2
1 A
1 B
1 C
2 D
2 E
When I run my where clause of col1 = 1, it returns the first three rows from the above table. What I want is the following table, but with only one execution of the where statement, since the two tables A and B are identical:
A.COL1 A.COL2 B.COL1 B.COL2
1 A 1 A
1 A 1 B
1 A 1 C
1 B 1 A
1 B 1 B
1 B 1 C
1 C 1 A
1 C 1 B
1 C 1 C
You are basically asking for an intentional Cartesian join
select
a.col1,
a.col2,
b.col1,
b.col2
from
tbl a
join tbl b
on a.col1 = b.col1
where
a.col1 = 1
order by
a.col2,
b.col2
To exactly hit your output order sequence, you need the order by by the "a" column 2 then "b" column 2
I really recommend avoiding that JOIN syntax... it can be very difficult to read.
Your explanation of what you are trying to do is a bit cryptic. The query as written offers no value for a JOIN operation. Generally speaking, when you want to JOIN a table to itself, it's on different columns:
select *
from tbl as a
inner join
table as b
on a.col1 = b.col2
where
a.col1 = 1;
This allows you to query against the table, and also collect related information organized in a hierarchical fashion in the same table. For example:
create table tbl (
person_id int,
parent_id int
);
In this case, a parent is a person too. If you wanted to get a list of the parents related to the person with an ID of 1, you could write:
select
person.person_id as OriginalPerson,
parent.person_id as Parent
from
tbl as person
inner join
tbl as parent
on parent.person_id = person.person_id
where
person.person_id = 1;
UPDATE Upon reading your further explanation, you want a cartesian product:
select a.*, b.*
from tbl as a
inner join tbl as b
on 1=1
where a.col1 = 1
and b.col1 = 1