How to use CONCAT_WS/GROUP_CONCAT in LIKE Mysql? - mysql

I am trying to execute below query which says
SELECT t1.name from table t1, t2 WHERE t2.data LIKE(CONCAT_WS(',' DISTINCT(t1.name)))
OR
SELECT t1.name from table t1, t2 WHERE t2.data LIKE(GROUP_CONCAT(DISTINCT(t1.name) SEPARATOR ','))
Both ways say
#1111 - Invalid use of group function

Well not totally sure what trying to do, but suspect will need a subquery to join on an aggregate function.
SELECT names
FROM t2
INNER JOIN (SELECT GROUP_CONCAT(DISTINCT name SEPARATOR ',') as names
FROM t1
GROUP BY user_id) t1 USING t2.data = names
That query still doesnt really make sence, but might show roughly how to construct it.
As comments say, really need more context to under WHAT you trying to do.

Related

MySql joining table with condition [duplicate]

I have a table id1, id2, type. type is an enumerated value containing a name of another table.
I'd like to preform a join with the name of the table of type.
For example:
switch($type)
case 'table1':
join table1;
break;
case 'table2':
join table2;
break;
How can I achieve this?
You can't do it directly like that... you can do something like this though (not very pretty...):
SELECT
t.id,
t.type,
t2.id AS id2,
t3.id AS id3
FROM t
LEFT JOIN t2 ON t2.id = t.id AND t.type = 't2'
LEFT JOIN t3 ON t3.id = t.id AND t.type = 't3'
ugly way:
Table Types, T1, T2:
SELECT ... FROM Types, T1 , where Types.ID=T1.Types_ID AND Types.TYPE='TABLE1'
UNION
SELECT ... FROM Types, T2 , where Types.ID=T2.Types_ID AND Types.TYPE='TABLE2'
In addition to previous answer:
You can combine the two left joins results by using IF statement:
IF(t.type= 't2', t2.id, t3.id) as type_id
You can see another mysql conditional joins example at mysqldiary.com
I needed to implement such a thing with Laravel Query Builder. I was preparing a library and shouldn't rebuild the whole query, I wanted to utilize Eloquent as much as possible so I could only add a join to the query. This could be a little closer to what you want but also a lot uglier than you would expect:
SELECT
`comments`.*,
`commentable`.`created_at` AS `commentable_created_at`
FROM
`comments`
LEFT JOIN ((
SELECT
*,
CONCAT('post_', `id`) AS `morphed_key`
FROM
`posts`)
UNION (
SELECT
*,
CONCAT('image_', `id`) AS `morphed_key`
FROM
`images`)) AS `commentable` ON
CONCAT(`comments`.`commentable_type`, '_', `comments`.`commentable_id`)= `commentable`.`morphed_key`
The point of using this way is that you are now able to add WHERE clauses like WHERE commentable.owner_id=?

MySQL unmatched records with additional fields

I have the following query which works just fine:
SELECT lastname, firstname, date, complete
FROM table1
WHERE complete NOT IN (SELECT complete FROM table2)
ORDER BY lastname
I'm being asked to provide information from columns that are in table2 but NOT in table1. Like so:
SELECT t1.lastname, t1.firstname, t1.date, t1.complete, t2.newdata
FROM table1 t1, table2 t2
WHERE t1.complete NOT IN (SELECT t2.complete FROM table2)
ORDER BY lastname
However, either this does not work or it somehow got caught in a loop because I had to kill the process after 2 hours.
Is there a way to include data from the table which is being compared (table2)?
I think you question is a little too broad, what is your requirements for t2.newdata?
What you are trying to do doesn't appear to me like it would ever work. You want to get newData from t2, where t2.complete != t1.complete, so how do you know which values of t2 to use? And how do you know which rows to match them with?
I think and I will await a comment from you to know for sure, is that you want all of that information from table 1, and only the information from table 2 when it matches. This describes an outer join.
Try something like this:
SELECT t1.lastName, t1.firstName, t1.date, t1.complete, t2.newData
FROM table1 t1
LEFT JOIN table2 t2 ON t2.complete = t1.complete
ORDER BY t1.lastName;
As I said, this will select all rows from table1, and will put a value in the newData column wherever the complete field has a matching row in table2. If there is not a matching row, the value is null.
See this SQL Fiddle, as well as the above outer join link for more info.
Try this:
SELECT t1.lastname, t1.firstname, t1.date, t1.complete, t2.newdata
FROM table1 t1
join table2 t2 on t2.id=t1.id and t1.complete !=t2.complete
ORDER BY t1.lastname

MySQL referencing nested query result in the SELECT?

Say you have two tables with columns:
table1: id, data
table2: id, t1_ref (which is a FK to table1), some_other_column
Now I can write something like (I know that this can be written differently, more efficient, etc, not looking for those):
SELECT t1.data,
(SELECT count(*)
FROM table2 t2
WHERE t2.t1_ref = t1.id) AS nested_result
FROM table1 t1;
My question is, where can I use 'nested_result' in the rest of the main query? Can I use it in the FROM (in another nested select for instance)? Or in the WHERE? Or in a GROUP BY? Or on a ORDER BY? Anywhere else?
For example MySQL doesn't seem to like:
SELECT t1.data,
(SELECT count(*)
FROM table2 t2
WHERE t2.t1_ref = t1.id) AS nested_result
FROM table1 t1
WHERE nested_result > 100;
but what are the general rules here?
nested_result is a column alias.
You can use it in the group by, having, and order by clauses.
You can put this whole statement in a subquery, and use it in the outer query.
Here is the reference in the documentation:
The following list provides additional information about other SELECT
clauses:
A select_expr can be given an alias using AS alias_name. The alias is
used as the expression's column name and can be used in GROUP BY,
ORDER BY, or HAVING clauses. For example:
SELECT CONCAT(last_name,', ',first_name) AS full_name
FROM mytable
ORDER BY full_name;
EDIT:
For your particular example, you can change the where to having:
SELECT t1.data,
(SELECT count(*)
FROM table2 t2
WHERE t2.t1_ref = t1.id
) AS nested_result
FROM table1 t1
HAVING nested_result > 100;
This is a MySQL extensions and doesn't work in other databases. As much as I don't like it, I have to admit that it is convenient.

MySQL Query with join and Alias without table name

i encountered a funny problem:
I have two table t1 and t2 with several columns. Because two columns in the both tables have the same name, i need to to this:
SELECT t1.foo AS ID, t2.bar as NAME
FROM t1, t2
WHERE t1.foo = t2.foo;
The Answers are headed with t1.ID, t2.NAME
I donĀ“t wont the table names in the headlines.
Funny thing: Using the same query in a view returns the correct / wanted headings: ID...NAME
I want to use those queries in stored procedures where the same behaviour has been observed.
Tried with MySQL 5.5.9
Any idea how to avoid the table names in the headlines?
SELECT ID, NAME
FROM (SELECT t1.foo AS ID, t2.bar as NAME
FROM t1, t2
WHERE t1.foo = t2.foo) AS t;
You can strip the linked tablename from a field with a simple string or int function:
SELECT (t1.foo+0) AS ID, CONCAT(t2.bar) as NAME
FROM t1, t2
WHERE t1.foo = t2.foo;

conditional join in mysql

I have a table id1, id2, type. type is an enumerated value containing a name of another table.
I'd like to preform a join with the name of the table of type.
For example:
switch($type)
case 'table1':
join table1;
break;
case 'table2':
join table2;
break;
How can I achieve this?
You can't do it directly like that... you can do something like this though (not very pretty...):
SELECT
t.id,
t.type,
t2.id AS id2,
t3.id AS id3
FROM t
LEFT JOIN t2 ON t2.id = t.id AND t.type = 't2'
LEFT JOIN t3 ON t3.id = t.id AND t.type = 't3'
ugly way:
Table Types, T1, T2:
SELECT ... FROM Types, T1 , where Types.ID=T1.Types_ID AND Types.TYPE='TABLE1'
UNION
SELECT ... FROM Types, T2 , where Types.ID=T2.Types_ID AND Types.TYPE='TABLE2'
In addition to previous answer:
You can combine the two left joins results by using IF statement:
IF(t.type= 't2', t2.id, t3.id) as type_id
You can see another mysql conditional joins example at mysqldiary.com
I needed to implement such a thing with Laravel Query Builder. I was preparing a library and shouldn't rebuild the whole query, I wanted to utilize Eloquent as much as possible so I could only add a join to the query. This could be a little closer to what you want but also a lot uglier than you would expect:
SELECT
`comments`.*,
`commentable`.`created_at` AS `commentable_created_at`
FROM
`comments`
LEFT JOIN ((
SELECT
*,
CONCAT('post_', `id`) AS `morphed_key`
FROM
`posts`)
UNION (
SELECT
*,
CONCAT('image_', `id`) AS `morphed_key`
FROM
`images`)) AS `commentable` ON
CONCAT(`comments`.`commentable_type`, '_', `comments`.`commentable_id`)= `commentable`.`morphed_key`
The point of using this way is that you are now able to add WHERE clauses like WHERE commentable.owner_id=?