I want to get * from concrete_samples but only method_name and not the id from concrete_compaction_methods
SELECT * FROM concrete_samples,concrete_compaction_methods WHERE concrete_compaction_methods.id = concrete_samples.compaction_method AND workorder_id=1
This is currently returning everything I want EXCEPT it's giving me the id column of the methods table which I don't want.
the pseudo code of the statement I want to do is
SELECT * FROM concrete_samples, SELECT method_name FROM concrete_compaction_methods WHERE concrete_compaction_methods.id = concrete_samples.compaction_method AND workorder_id=1
I've done some research. I've tried to use a union but i don't think that's the correct or neatest solution
Thank you
I strongly advise:
Learn to use proper JOIN syntax.
Use table aliases in your query.
Qualify all column references.
So the query looks more like this:
SELECT cs.*, ccm.method_name
FROM concrete_samples cs JOIN
concrete_compaction_methods ccm
ON ccm.id = cs.compaction_method
WHERE cs.workorder_id = 1;
I am guessing that workorder_id comes from concrete_samples rather than the other table.
Try below -
SELECT concrete_samples.*,method_name
FROM concrete_samples inner join concrete_compaction_methods
on concrete_compaction_methods.id = concrete_samples.compaction_method
where workorder_id=1
Related
I have two tables (PlayerDTO and ClubDTO) and am using a JOIN to fetch data as follows:
SELECT * FROM PlayerDTO AS pl
INNER JOIN ClubDTO AS cl
ON pl.currentClub = cl.id
WHERE cl.nation = 7
This returns the correct rows from PlayerDTO, but in every row the id column has been changed to the value of the currentClub column (eg instead of pl.id 3,456 | pl.currentClub 97, it has become pl.id 97 | pl.currentClub 97).
So I tried the query listing all the columns by name instead of Select *:
SELECT pl.id, pl.nationality, pl.currentClub, pl.status, pl.lastName FROM PlayerDTO AS pl
INNER JOIN ClubDTO AS cl
ON pl.currentClub = cl.id
WHERE cl.nation = 7
This works correctly and doesn’t change any values.
PlayerDTO has over 100 columns (I didn’t list them all above for brevity, but I included them all in the query) but obviously I don’t want to write every column name in every query.
So could somebody please explain why Select * changes the id value and what I need to do to make it work correctly? All my tables have a column called id, is that something to do with it?
SELECT *... is, according to the docs...
shorthand for “select all columns.” (Source: Dev.MySQL.com
Both your tables have id columns, so which should be returned? It's not indicated, so MySQL makes a guess. So select what you want to select...
SELECT pl.id, *otherfieldsyouwant* FROM PlayerDTO AS pl...
Or...
SELECT pl.* FROM PlayerDTO AS pl...
Typically, SELECT * is bad form. The odds you are using every field is astronomically low. And the more data you pull, the slower it is.
I have the following query:
select x.id0
from (
select *
from sessions
inner join clicked_products on sessions.id0 = clicked_products.session_id0
) x;
Since id0 is in both sessions and clicked_products, I get the expected error:
column reference "id0" is ambiguous
However, to fix this problem in the past I simply needed to specify a table. In this situation, I tried:
select sessions.id0
from (
select *
from sessions
inner join clicked_products on sessions.id0 = clicked_products.session_id0
) x;
However, this results in the following error:
missing FROM-clause entry for table "sessions"
How do I return just the id0 column from the above query?
Note: I realize I can trivially solve the problem by getting rid of the subquery all together:
select sessions.id0
from sessions
inner join clicked_products on sessions.id0 = clicked_products.session_id0;
However, I need to do further aggregations and so do need to keep the subquery syntax.
The only way you can do that is by using aliases for the columns returned from the subquery so that the names are no longer ambiguous.
Qualifying the column with the table name does not work, because sessions is not visible at that point (only x is).
True, this way you cannot use SELECT *, but you shouldn't do that anyway. For a reason why, your query is a wonderful example:
Imagine that you have a query like yours that works, and then somebody adds a new column with the same name as a column in the other table. Then your query suddenly and mysteriously breaks.
Avoid SELECT *. It is ok for ad-hoc queries, but not in code.
select x.id from
(select sessions.id0 as id, clicked_products.* from sessions
inner join
clicked_products on
sessions.id0 = clicked_products.session_id0 ) x;
However, you have to specify other columns from the table sessions since you cannot use SELECT *
I assume:
select x.id from (select sessions.id0 id
from sessions
inner join clicked_products
on sessions.id0 = clicked_products.session_id0 ) x;
should work.
Other option is to use Common Table Expression which are more readable and easier to test.
But still need alias or selecting unique column names.
In general selecting everything with * is not a good idea -- reading all columns is waste of IO.
I am currently learning SQL using Oracle SQL developer.
While writing queries I came up with three different versions of the same query.
SELECT
sh.share_id
FROM shares sh
LEFT JOIN trades tr
ON sh.share_id = tr.share_id
WHERE trade_id is NULL;
SELECT
sr.share_id
FROM (SELECT sh.share_id, tr.trade_id
FROM shares sh
LEFT JOIN trades tr
ON sh.share_id = tr.share_id) sr
WHERE sr.trade_id is NULL;
SELECT
sr.share_id
FROM (SELECT *
FROM shares sh
LEFT JOIN trades tr
ON sh.share_id = tr.share_id) sr
WHERE sr.trade_id is NULL;
The first two queries compile, run and return the same result set but when I try to run the third query I get a error on the second line of the third query.
"SR"."SHARE_ID": invalid identifier.
I know that * in the SELECT statement selects all columns so why Am I getting this error?
From reading your comments, in your final query, the DBMS doesn't know which share_id to use for your SELECT sr.share_id. AKA the SELECT * of your subquery is grabbing two share_id columns. You have to do something like your 2nd query.
The problem is that select * is selecting all columns from both tables, even those with the same name. So, you are getting share_id twice. A simple fix is to use USING:
SELECT sr.share_id
FROM (SELECT *
FROM shares sh LEFT JOIN
trades tr
USING (share_id)
) sr
WHERE sr.trade_id is NULL;
Of course, tis only fixes the reference to share_id.
Basicly I have tables much like picture below.
At first I'm getting SaleOrderID by given CustomerID :
Select
SaleOrderID
From tblSaleOrder
where CustomerID = 512992
Which returns, 1002,1003,1005,1009
And I want to use that numbers for select from tblSaleOrderDetail :
Select
*
from tblSaleOrderDetail
where SaleOrderID = 1002,1003,1005,1009
(values from other query)
I need suggestion on query to use values from another select. Is there a way to create array to hold values then use it for another query ? OR a easier way !
Use a subselect within an in clause:
select *
from tblSaleOrderDetail
where SaleOrderID in (
select SaleOrderID
from tblSaleOrder
where CustomerID = 512992)
When using a subselect within an in clause remember that you must only select one column within the subselect.
You could also perform a join:
select *
from tblSaleOrderDetail sod
join tblSaleOrder so
on sod.SaleOrderId = so.SaleOrderId
where so.CustomerID = 512992
This is a very basic SQL operation, called the join. Although you can use in for this purpose, the more typical way is:
select sod.*
from tblSaleOrder so join
tblSaleOrderDetail sod
on so.SaleOrderID = sod.SaleOrderID
where so.CustomerID = 512992;
If you are learning SQL, the join operation is one of the first things you should be learning.
Probably going a bit overkill on this post since the question is fairly basic but I wanted to give you a list of options as well as some basic advice. One of the simplest ways to do this is by using the IN clause. The IN clause conceptually works a lot like = except it looks for a list of items.
Example
Select
*
from tblSaleOrderDetail
where SaleOrderID IN
(
Select
SaleOrderID
From tblSaleOrder
where CustomerID = 512992
)
Yet another way to accomplish this is by using EXISTS. Which works very much like it sounds it checks for rows that exist in the other table.
Select
*
from tblSaleOrderDetail AS SOD
where EXISTS
(
Select
1
From tblSaleOrder AS SO
where CustomerID = 512992
AND SOD.SaleOrderID = SO.SaleOrderID
)
Notice how I use AS SO and SOD to give those tables new names. This is called aliasing and it is your friend. I highly recommend using it in you future queries.
You can use JOIN as well however when I started writing this there was already an example of this.
I'm trying to execute seemingly simple request contains WITH clause:
WITH sub AS (SELECT url FROM site WHERE id = 15)
SELECT * FROM search_result WHERE url = sub.url
But it doesn't work. I get
ERROR: missing FROM-clause entry for table "sub"
What's the matter?
Table expressions need to be used like tables. You're trying to use the value of sub as a scalar.
Try this (forgive me, Postgres is not my first SQL dialect).
WITH sub AS (SELECT url FROM site WHERE id = 15)
SELECT * FROM sub
INNER JOIN
search_result
ON
sub.url = search_result.url
EDIT, alternatively, you could just skip the WITH clause and go with:-
SELECT * FROM
site
INNER JOIN
search_result
ON
site.url = search_result.url
WHERE
site.id = 15
Don't use a CTE at all for this simple case.
Unlike you seem to be expecting, the following simple query without a CTE will be slightly faster:
SELECT r.*
FROM search_result r
JOIN site s USING (url)
WHERE s.id = 15;
Test with EXPLAIN ANALYZE to verify.
CTEs introduce an optimization barrier. They have many very good uses, but they won't make simple queries faster.
Here is a thread on pgsql-performance that gives you more details as to why that is.
That's not the correct way to use a CTE:
With sub as (
SELECT url
FROM site
WHERE id = 15
)
SELECT *
FROM Search_Result SR
JOIN sub ON SR.url = sub.Url
You can just as easily do an inner join:
SELECT search_result .*
FROM
search_result
INNER JOIN
(SELECT url FROM site WHERE id = 15) as st
ON
search_result.url = st.url
This does the filtering so that you are joining on a smaller set than if you did the where clause outside of the filtering. This may not matter in your case, but it is something to consider.