I have two select:
SELECT ID, ID_cat, modello
FROM tbArticoli
WHERE ID_cat=5
Example result in Json:
{"ID":"5","ID_cat":"5","modello":"Hawaii"},
{"ID":"6","ID_cat":"5","modello":"T-Shirt Righe"},
{"ID":"7","ID_cat":"5","modello":"Polo"},
{"ID":"8","ID_cat":"5","modello":"Fantasia"},
{"ID":"9","ID_cat":"5","modello":"Fiori"},
{"ID":"10","ID_cat":"5","modello":"Arcobaleno"},
{"ID":"11","ID_cat":"5","modello":"Oro"},
{"ID":"12","ID_cat":"5","modello":"Argento"},
{"ID":"13","ID_cat":"5","modello":"StelleStrisce"}
And another select:
SELECT IDModello,
FLOOR(AVG(voto)) AS votomedio
FROM tbCommenti
GROUP BY IDModello
with result:
{"IDModello":"5","votomedio":"7"},
{"IDModello":"6","votomedio":"7"},
{"IDModello":"7","votomedio":"8"},
{"IDModello":"8","votomedio":"6"}
I need a final result like this:
{"ID":"5","ID_cat":"5","modello":"Hawaii","votomedio":"7"},
{"ID":"6","ID_cat":"5","modello":"T-Shirt Righe","votomedio":"7"},
{"ID":"7","ID_cat":"5","modello":"Polo","votomedio":"8"},
{"ID":"8","ID_cat":"5","modello":"Fantasia","votomedio":"6"},
{"ID":"9","ID_cat":"5","modello":"Fiori","votomedio":"null"},
{"ID":"10","ID_cat":"5","modello":"Arcobaleno","votomedio":"null"},
{"ID":"11","ID_cat":"5","modello":"Oro","votomedio":"null"},
{"ID":"12","ID_cat":"5","modello":"Argento","votomedio":"null"},
{"ID":"13","ID_cat":"5","modello":"StelleStrisce","votomedio":"null"}
on tbArticoli.ID = tbCommenti.IDModello
Which is the best query?
Thank you.
Assuming you want to join on id = idmodello, you can do something like
SELECT *
FROM (SELECT ID, ID_cat, modello
FROM tbArticoli
WHERE ID_cat=5) AS tbA
LEFT JOIN (SELECT IDModello,
FLOOR(AVG(voto)) AS votomedio
FROM tbCommenti
GROUP BY IDModello) as tbC
ON tbA.ID = tbC.IDModello
You can specify subqueries as what you are selecting from, because MySQL selects from a set of tuples. The table name just specifies that you want all tuples from that table, whereas in the query above you are specifying the specific tuples that you want. The main thing to note in this query is that you must use the 'AS' keyword to specify a temp name for each set of tuples.
Related
We have two tables in mysql database.Screenshots are attached below.
Given table ads_testTable
here is the screenshot of my dimesnionvalue_flattable
We have to run a query like the one below.
SELECT Quiz_Attempt.L1_Key dimID,
Quiz_Attempt.L1_Label CatVars,
COALESCE(**xyz**,0) AS series0
FROM DSQ_ADSSCHEMA.ADS_TestTable dataTable
RIGHT OUTER JOIN LS_CONFIG.DSQ_DIMENSIONVALUES_FLAT Quiz_Attempt on dataTable.Quiz_Attempt = Quiz_Attempt.L1_Key
WHERE Quiz_Attempt.L0_Key = 'All Levels' AND
Quiz_Attempt.DimensionID = 'Packet'
GROUP BY Quiz_Attempt.L1_Key, Quiz_Attempt.L1_Label;
My motive is to write a query in place of xyz so that I can get avg of obtainedMarks column in testtable according to the value of dimID I get.Each distinct Quiz_Attempt is a different test so If a Packet is repeating for a particular Quiz_Attempt in testTable, it should take only one value for that AttemptID.
I think you query could take the form of:
SELECT
L1_Key dimID,
L1_Label CatVars,
COALESCE('**xyz**',0) AS series0
FROM (
SELECT *
FROM (SELECT * FROM ADS_TestTable GROUP BY ADS_TestTable.Quiz_Attempt) dataTable
RIGHT OUTER JOIN DSQ_DIMENSIONVALUES_FLAT Quiz_Attempt on dataTable.Quiz_Attempt = Quiz_Attempt.L1_Key
WHERE Quiz_Attempt.L0_Key = 'All Levels' AND
Quiz_Attempt.DimensionID = 'Packet'
GROUP BY dataTable.Quiz_Attempt
) A GROUP BY dimID, CatVars;
The JOIN is done in an inner query, and grouped by Quiz_Attempt, so that you get a single row per attempt. This result is then used to compute what you need.
select * from user_levels
join collectors_users on user_levels.id = collectors_users.user_level
where collectors_users.username = 'testuser'
I want it to pull everything from user_levels and nothing from collectors_users. But it's pulling from both. How do I correct the statement?
Instead of select * specify what you actually want and use select user_levels.* or even better skip the * and write out the columns you want (and consider using aliases to keep it short and tidy): select ul.col1, ul.col2 ... from userlevels ul join ...
It is getting all the data as the '*' means 'all' columns. You can limit the columns for just one table by specifying the table:
select user_levels.*
from user_levels
join collectors_users on user_levels.id = collectors_users.user_level
where collectors_users.username = 'testuser'
Pro tip: Don't use SELECT * in running software. Instead, be as specific as you can be about the columns you want in your result set.
SELECT user_levels.*
should help a bit.
I might suggest that you use in or exists, because this is more consistent with the intention of the query:
select ul.*
from user_levels ul
where ul.id in (select cu.user_level
from collectors_users cu
where cu.username = 'testuser'
);
In addition, this version will not produce duplicate rows if collectors_users has multiple matching rows for a singel row in user_levels.
Also note the use of table aliases: these make the query easier to write and to read.
I have these 2 queries:
$sql = "SELECT *
FROM ultrait_wpl_properties
LEFT JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id ";
$sql2 = "SELECT *
FROM ultrait_wpl_properties, ultrait_wpl_property_types
WHERE ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id";
For some odd reason when the IDs are output some are duplicated? By my reseaning these queries should get everything from the table in the first part and join the second table based on the WHERE condition.
<property><id>13</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>7</id></property>
This may be slightly unclear but for some reason I'm getting duplicate IDs, all i want really is to be able to access the property type which links to the ID in the second table.
I have tested both queries in phpMyAdmin and they yeild the desired result, however when I use the queries in my php script they return unexpected results.
You are getting one row for each row in table ultrait_wpl_properties. What else do you expect? If it is just one record per type, then you would have to re-write your query accordingly. You select * from both tables. But is it only the type ID you need? Then why join the tables at all?
Get all type IDs:
select id from ultrait_wpl_property_types;
Get all type IDs in table ultrait_wpl_properties:
select distinct property_type from ultrait_wpl_properties;
Get all type data for types in ultrait_wpl_properties:
select * from ultrait_wpl_property_types
where id in (select property_type from ultrait_wpl_properties);
You are getting a Cartesian result in the case the ultrait_wpl_property_types table has multiple records for a single property. Such as a property type could be Type A, Type B, Type C which might be descriptive "types". So a single property would be accounted for each entry.
You might just need to do SELECT DISTINCT, or GROUP BY ultrait_wpl_properties.id to make sure only one record per ID, but with generic "Select * ", I would first try with GROUP BY.
Let's say I have two tables, and both their primary identifiers use the name 'id'. If I want to perform a join with these two tables, how would I alias the id of the table that I want to join with the former table?
For example:
SELECT * FROM `sites_indexed` LEFT JOIN `individual_data` ON `sites_indexed`.`id` = `individual_data`.`site_id` WHERE `url` LIKE :url
Now, site_id is supposed to link up with sites_indexed.id. The actual id which represents the row for individual_data however has the same title as sites_indexed.
Personally, I like to just use the name id for everything, as it keeps things consistent. When scripting server-side however, it can make things confusing.
e.g.
$var = $result['id'];
Given the aforementioned query, wouldn't this confuse the interpreter?
Anyway, how is this accomplished?
Instead of selecting all fields with "SELECT *" you should explicitly name each field you need, aliasing them with AS as required. For example:
SELECT si.field1 as si_field1,
si.field2 as si_field2,
ind_data.field1 as ind_data_field1
FROM sites_indexed as si
LEFT JOIN individual_data as ind_data
ON si.id = ind_data.site_id
WHERE `url` LIKE :url
And then you can reference the aliased names in your result set.
This thread is old and i found because i had the same problem. Now i have a better solution.
The answer given by Paul McNett and antun forces you to list all fields but in some cases this is impossible (too much fields to list), so you can keep the * and alias only the fields you want (typically the fields that have the same name and will override each other).
Here's how :
SELECT *, t.myfield as myNewName
FROM table t ... continue your query
you can add as much aliases as you want by adding comas.
Using this expression you will get results with columns id (from table sites_indexed) and id2 (alias for column id from table individual_data)
SELECT t1 . *, t2 . * FROM sites_indexed t1
LEFT JOIN (select id as id2, other_field1, other_field2 FROM individual_data) t2 ON t1.id = t2.site_id WHERE your_statement
The problem is that you're using the * wildcard. If you explicitly list the column names in your query, you can give them aliases:
SELECT `sites_indexed`.`id` AS `sites_indexed_id`,
`individual_data`.`id` AS `individual_data_id`
FROM `sites_indexed`
LEFT JOIN `individual_data` ON `sites_indexed`.`id` = `individual_data`.`site_id`
WHERE `url` LIKE :url
Then you can reference them via the alias:
$var = $result['sites_indexed_id'];
$var_b = $result['individual_data_id'];
I need to get a title from table 2, table 2 has title and id column.
Table 1 has some data and three of these columns concatenated together makeup the id that can be found in table 1.
I used CONCAT_WS() function and gave this column an alias name and need to use the Alias for the on argument(At least this is what I understood I needed to do)
I thought this could be a simple left join, yet it is not working for me.
This is my query
SELECT
table_openers.mail,
table_openers.f_name,
table_openers.l_name,
table_openers.Quality,
CONCAT_WS('-',
table_openers.esp,
table_openers.acc,
table_openers.group) as 't1aid',
table_groups.aid,
table_groups.group_name
FROM
lance_mailstats.table_openers
LEFT JOIN
lance_mailstats.table_groups ON table_groups.aid = t1aid;
I get results for mail, f_name, l_name, Quality and t1aid, but the aid and group_name columns of the second table return null.
I feel like you can't use an alias in the ON clause.
Try doing
LEFT JOIN
lance_mailstats.table_groups ON table_groups.aid = CONCAT_WS('-',
table_openers.esp,
table_openers.acc,
table_openers.group);
"You can use the alias in GROUP BY, ORDER BY, or HAVING clauses to refer to the column" (from dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html).
And "The conditional_expr used with ON is any conditional expression of the form that can be used in a WHERE clause" (from dev.mysql.com/doc/refman/5.1/en/join.html).
So as a logical inference you're not allowed to use aliases in ON clauses.
try to use a subquery..
it goes like this.........
ex.
SELECT
tbl1.mail, tbl1.f_name, tbl1.l_name,tbl1.Quality, tbl1.t1aid,table_groups.aid,
table_groups.group_name
FROM
(SELECT
table_openers.mail,
table_openers.f_name,
table_openers.l_name,
table_openers.Quality,
CONCAT_WS('-',
table_openers.esp,
table_openers.acc,
table_openers.group) as 't1aid',
FROM
lance_mailstats.table_openers )tbl1
LEFT JOIN
lance_mailstats.table_groups ON table_groups.aid = tbl1.t1aid;