MySQL - dont show any row from ID use - mysql

I just need to show the values that don't use the specifically ID.
I have two table
table 1
id_xx
1
2
3
4
5
table 2
id | id_xx
3 | 3
4 | 3
4 | 1
I need this results for example. I say which results from ID i need
i need this result where id=3
id_xx
1
2
4
5
or where id=4
id_xx
2
4
5
or where id=1
1
2
3
4
5

You can LEFT JOIN table1 with table2 and apply the filter in the ON clause of the JOIN, and then filter on unmatched records:
SELECT t1.id_xx
FROM table1 t1
LEFT JOIN table2 t2 ON t2.id_xx = t1.id_xx AND t2.id = ?
WHERE t2.id IS NULL
You can replace the question mark with the id that you need to check.
Demo on DB Fiddle:
Given t2.id = 3:
| id_xx |
| ----- |
| 1 |
| 2 |
| 4 |
| 5 |
Given t2.id = 4:
| id_xx |
| ----- |
| 2 |
| 4 |
| 5 |

Another approach is using a Correlated Subquery with NOT EXISTS():
SELECT t1.id_xx
FROM table1 AS t1
WHERE NOT EXISTS (SELECT 1
FROM table2 AS t2
WHERE t2.id = ? -- your input id here
AND t2.id_xx = t1.id_xx)
If you have large table(s), and are worried about performance of these queries, then you may define the following index:
For the correlated subquery, define composite index (id, id_xx) on table2.
ALTER TABLE table2 ADD INDEX(id, id_xx);
Assuming that id_xx is already a Primary Key in the table1. So, you don't need to define any index there. If not, then you can define an index on it.

Related

Update without where clause

+------+------+
| id | no |
+------+------+
| 1 | 1 |
| 11 | 1 |
| 21 | 1 |
+------+------+
I want to update 2nd row no. to 2.
the query i can use is
update test set no = 2 where id = 11;
How can i achieve the same without where clause ??
I am not sure why you would want to but...
UPDATE `test` SET `no` = IF(`id`=11, 1, `no`);
For the record, I would be surprised if this didn't perform horribly as it would go through every row in the table.
To update the "second" row in the table, the row that has the second smallest id value...
UPDATE test t
JOIN ( SELECT r.id
FROM test r
ORDER BY r.id
LIMIT 1,1
) s
ON s.id = t.id
SET t.no = 2
EDIT
As a followup to clarify the results of the query above...
In the case where id is not unique in the table, the query could potentially update more than one row. The inline view query (s) gets the id value from the "second" row, after the rows are ordered by id value. Then all rows that have that same id value would be updated.
This is an issue only if id is not unique; if id is unique, the statement would update (at most) one row.
For example, if the contents of the table was:
+-----+-----+
| id | no |
+-----+-----+
| 1 | 1 |
| 11 | 3 | <-- "second" row, ordered by id ascending
| 11 | 4 | <-- id from third row matches id from second row
| 21 | 1 |
+-----+-----+
The result of the query above would be to update the two rows that have id value of 11.
+-----+-----+
| id | no |
+-----+-----+
| 1 | 1 |
| 11 | 2 | <-- updated
| 11 | 2 | <-- updated
| 21 | 1 |
+-----+-----+
That´s not possible, a update without where is an update to all the table. You can try this, but it is always like a where:
update test set no = case id when 11 then 2 else no end
This doesn't use a where clause and it might be a bit faster than using if() or case:
update test t join
(select 1 as dum) dum
on t.id = 11
set t.no = 2 ;
And yet a 3rd way...
update test A INNER JOIN test B
on A.ID = B.ID
and B.ID = 11
set A.No = 2;
For clarity this does a self join on a table that only has record 11, thus updating only record 11 (b.iD = 11). using an ON Clause.

Two SELECT's in one query in the same table

I have one table:
id | parent_id | name
1 | NULL | audi
2 | 1 | a5
3 | 1 | a6
4 | NULL | opel
5 | 4 | astra
6 | 4 | vectra
I want get name of record and name of record's parent.
One example is to fetch the name for id=5 and its parent name.
id | name | parent_name
5 | astra | opel
What would be SQL query for this?
My query:
SELECT name, parent_id FROM `cats` WHERE `id` = 5 OR `id` =
cats.parent_id LIMIT 0 , 30
didn't work.
You can use the below query:
SELECT T1.id, T1.name, T2.name as parentname
FROM TABLE1 T1
INNER JOIN TABLE1 T2 ON T1.id = T2.parent_id
WHERE T2.ID = 5
SQL FIDDLE
This work's if you have only 1 parent at a time (no recursion):
SELECT a.name name, b.name parent_name
FROM tablexyz a,tablexyz b where
a.id=5 AND a.parent_id=b.id;
This worked fine for me. Please check it out.
select a.id,a.name,b.name as parent from cats a,cats b where b.id=a.parent_id;
You can add any other conditions too. (make sure to use the correct table identifier; a or b)

Query to find if a foreign key is set

OK, I have two MySQL Tables:
TableA containing the following columns: idTableA and idTableB_FK
TableB containing the following columns: idTableB and idTableA_FK
The relationships are as follows:
One-to-Many relationship from TableA to TableB (TableA.idTableA is
the PK, and the FK for that relationship is TableB.idTableA_FK)
One-to-One relationship between TableA and TableB (TableB.idTableB
is the PK, and it is be represented in TableA.idTableB_FK). It is
a one-to-one relationship because you can only have one row in TableA to take a
foreign key value.
Assuming the following data in TableA
idTableA | idTableB_FK
-----------------------------
1 | 2
2 | 5
3 | 6
4 | 8
And the folloing in TableB
idTableB | idTableA_FK
------------------------------
1 | 1
2 | 1
3 | 2
4 | 2
5 | 2
6 | 3
7 | 3
8 | 4
Now, what I want a query that will display idTableA, idTableB, and will display is_set column. The is set is a yes/no field (or 1/0) where it is set to yes only if TableA.idTableB_FK has a corresponding set value for that FK. So for the above example:
idTableA | idTableB | is_set
---------------------------------------------
1 | 1 | no
1 | 2 | yes
2 | 3 | no
2 | 4 | no
2 | 5 | yes
3 | 6 | yes
3 | 7 | no
4 | 8 | yes
Thanks.
I think you are looking for something like this:
select
TableA.idTableA,
TableB.idTableB,
case when EXISTS(select null
from TableA TableA_1
where
TableA_1.idTableA = TableA.idTableA
and TableA_1.idTableB_FK = TableB.idTableB)
then 'yes' else 'no' end as is_set
from
TableB left join TableA
on TableB.idTableA_FK = TableA.idTableA
OK that was from memory but should do it. If it is wrong I can run it against something and fix it.
SELECT tb.idTableA_FK AS idTableA, tb.idTableB, tbb.idTableB IS NOT NULL AS is_set
FROM TableB AS tb LEFT JOIN TableA AS ta ON (tb.idTableA_FK = ta.idTableA)
LEFT JOIN TableB AS tbb ON (ta.idTableB_FK = tbb.idTableB)
I believe that this is what you're looking for:
SELECT a.idTableA, b.idTableB, c.idTableB_FK IS NOT NULL is_set
FROM TableA a, TableB b LEFT JOIN TableA c ON b.idTableB=c.idTableB_FK
WHERE b.idTableA_FK=a.idTableA
I ended up doing this:
SELECT b.idTableA_FK, b.idTableB ,
IF (
(SELECT a.idTableB_FK
FROM (TableA AS a)
WHERE a.idTableA = b.idTableA_FK
) = b.idTableB, TRUE, FALSE
) AS is_set
FROM (TableB AS b)
Which produced the correct results.
I like to thank all that responded, and I am voting up fthiella because his/her suggested solution was influential to my solution.

SELECTING SUM based on conditional if from another table

Database: mysql > ver 5.0
table 1: type_id (int), type
table 2: name_id, name, is_same_as = table2.name_id or NULL
table 3: id, table2.name_id, table1.type_id, value (float)
I want to sum values, and count values in table 3 where table2.name_id are same and also include the values of id where is_same_is=name_id. I want to select all data in table3 for all values in table2.
Apologize if my question is not very clear, and if it has already been answered but I am unable to find a relevant answer. Or dont exactly know what to look for.
[data]. table1
id | type
=========
1 | test1
2 | test2
[data].table2
name_id | name | is_same_as
==============================
1 | tb_1 | NULL
2 | tb_2 | 1
3 | tb_3 | NULL
4 | tb_4 | 1
[data].table3
id | name_id | type_id | value
======================================
1 | 1 | 1 | 1.5
2 | 2 | 1 | 0.5
3 | 2 | 2 | 1.0
output:
name_id| type_id|SUM(value)
=======================================================
1 | 1 |2.0 < because in table2, is_same_as = 1
2 | 2 |1.0
I think the following does what you want:
select coalesce(t2.is_same_as, t2.name_id) as name_id, t3.type_id, sum(value)
from table_3 t3 join
table_2 t2
on t3.name_id = t2.name_id
group by coalesce(t2.is_same_as, t2.name_id), t3.type_id
order by 1, 2
It joins the table on name_id. However, it then uses the is_same_as column, if present, or the name_id if not, for summarizing the data.
This might be what you are looking for: (I haven't tested it in MySQL, so there may be a typo)
with combined_names_tab (name_id, name_id_ref) as
(
select name_id, name_id from table2
union select t2a.name_id, t2b.name_id
from table2 t2a
join table2 t2b
on (t2a.name_id = t2b.is_same_as)
)
select cnt.name_id, t3.type_id, sum(t3.value) sum_val
from combined_names_tab cnt
join table3 t3
on ( cnt.name_id_ref = t3.name_id )
group by cnt.name_id, t3.type_id
having sum(t3.value) / count(t3.value) >= 3
Here's what the query does:
First, it creates 'combined_names_tab' which is a join of all the table2 rows that you want to GROUP BY using the "is_same_as" column to make that determination. I make sure to include the "parent" row by doing a UNION.
Second, once you have those rows above, it's a simply join to table3 with a GROUP BY and a SUM.
Note: table1 was unnecessary (I believe).
Let me know if this works!
john...

mysql select from one table if its name is in another table

So what I have is something like this:
main_table
id | in_table | in_tables_id | points
1 | t1 | 1 | 1
2 | t2 | 1 | 4
3 | t2 | 2 | 3
4 | t1 | 2 | 2
and then tables
table1 - which in my main_table is marked as t1
id | content_id
1 | 1
2 | 2
table2 - which in my main_table is marked as t2
id | content_id
1 | 1
2 | 2
content
id | category_id | content
1 | 1 | aaa
2 | 2 | bbb
categories
id | name
1 | first
2 | seccond
3 | third
So my first table "main_table" has ids of entries from "table1" and "table2" for which users got their points, those entries are connected to "content" by content_id = id from "content" table; and that content in "content" table is allways in some category from "categories" table.
What I want is to sum all points from "main_table" by categories from "categories" table.
The main problem for me is to somehow "connect" identifiers from "main_table" like t1, t2 with tables "table1", "table2", is there a way to do it?
I recommend restructuring your DB. Have a look at normal forms and transform your tables into normal form, e.g. don't use separate tables, but store the "table name" in a column, so you can do easy joins.
For your current table layout use something like the following join conditions:
select *
from main_table mt
inner join table1 t1
on mt.in_table = 't1'
and mt.in_tables_id = t1.id
inner join table2 t2
on mt.in_table = 't2'
and mt.in_tables_id = t2.id
/* repeat for number of tables */