Some doubts about this simple INNER JOIN query? - mysql

I have the following doubt about this simple INNER JOIN query.
I have these two tables that have to be joined togheter:
The first table is named VulnerabilityFix and contains the following columns:
Id: int identity
FixName: varchar
Vendor: varchar
Title: varchar
Version: varchar
The second table is named VulnerabilityAlertDocument_VulnerabilityFix (this bind the previous table to another table, but this is not important at this time) and contains the following columns:
VulnerabilityAlertDocumentId: int
VulnerabilityFixId: int
Now, on my DB the VulnerabilityFix table contains only an empty record (this record have an id but all the other fields are empty\null), infact if I perform a select *, I obtain:
select * from VulnerabilityFix
Id FixName Vendor Title Version
1
Into the VulnerabilityAlertDocument_VulnerabilityFix I have something like this:
select * from VulnerabilityAlertDocument_VulnerabilityFix
VulnerabilityAlertDocumentId VulnerabilityFixId
78385 1
78386 1
....................................................
....................................................
....................................................
78398 1
Ok, so I want JOIN toghert these 2 table in in such a way that passing the value of the VulnerabilityAlertDocumentId field of the VulnerabilityAlertDocument_VulnerabilityFix table, I obtain all the related record in the VulnerabilityFix table.
So in this case I aspect to retrieve the previous only record that having an id (having a value equal to 1) and all the other fields are empty\null.
So my query is:
SELECT VF.* FROM VulnerabilityAlertDocument_VulnerabilityFix VAD_VF
INNER JOIN VulnerabilityFix VF ON VAD_VF.VulnerabilityAlertDocumentId = VF.Id
WHERE VAD_VF.VulnerabilityAlertDocumentId = 1
The problem is that when I execute this query I obtain an empty set of records and not the unique record that I expetc to obtain.
Why? What am I missing?
Tnx

I think your query should be more like:
SELECT VF.* FROM VulnerabilityAlertDocument_VulnerabilityFix VAD_VF
INNER JOIN VulnerabilityFix VF ON VAD_VF.VulnerabilityFixId = VF.Id
WHERE VAD_VF.VulnerabilityAlertDocumentId = 78385
That is, you are using the wrong column at your ON condition since VulnerabilityFixId seems to be the foreign key over VulnerabilityFix.Id and not VulnerabilityAlertDocumentId.
On the other hand, I can't see any VulnerabilityAlertDocument_VulnerabilityFix.VulnerabilityAlertDocumentId with value 1 in you data set (where condition)

Related

mysql query works with some particular records only not with all of the data

first image of student_detail table,second is image of payment_detail table when i fire the query like
SELECT `student_detail`.`id`,
`student_detail`.`first_name`,
`student_detail`.`last_name`,
`student_detail`.`course`,
`payment_detail`.`id`,
`student_id`,
`inst_paid_date`,
`next_inst_date`,
`paid_installment`,
`next_installment_amount`
FROM `student_detail`,`payment_detail`
WHERE MONTH(`next_inst_date`)=MONTH(now())
AND `inst_paid_date`<`next_inst_date`
AND `student_detail`.`id`=`student_id`
AND `student_id`='10'
AND `inst_paid_date` in(select max(`inst_paid_date`) from `payment_detail`)
it do not give any result when records are present like second table but if i delete student id 8 and 9 it gives the result other wise not i cant get how it is conflict with other records when perticularly set the where condition with student_id=10. thanks in advanced
The reason is that you limit your inst_paid_date to the maximum value across the entire payment_detail table. Since this maximum value is for student id 9 when it is present, this conflicts with your filter on student id 10.
Try to add the same filter to your subquery like this:
WHERE
...
AND `student_id`='10'
AND `inst_paid_date` in (select max(`inst_paid_date`)
from `payment_detail`
where `student_id` = '10')
A more generic solution would be to turn the subquery into a correlated subquery. This requires an alias on the outer reference to the payment_detail table:
...
FROM `student_detail`,`payment_detail` as `PD`
WHERE MONTH(`next_inst_date`)=MONTH(now())
AND `inst_paid_date`<`next_inst_date`
AND `student_detail`.`id`=`student_id`
AND `PD`.`student_id`='10'
AND `inst_paid_date` in(select max(`inst_paid_date`)
from `payment_detail`
where `student_id` = `PD`.`student_id`)

Complicated MySql Update Join Query

Have is an example of the problem I'm facing. The database tables are a little different than usual, but needed to be setup this way.
Items: id, order_id, other fields
Items_Drinks: id, drinks, other fields
Orders: id, other fields
Orders_Drinks: id, drinks, other fields
I need to have an update query that will update the Orders_Drinks table with the sum of the Items_Drinks drinks field that have the same order_id as Orders_Drinks id field.
Items: 1 1 ...
Items: 2 1 ...
Items_Drinks: 1 4 ...
Items_Drinks: 2 5 ...
Orders: 1 ...
Orders_Drinks: 1 9 ...
The Orders_Drinks is currently correct, but if I were to update Items_Drinks with id of 1 to 5, I would need an update command to get Orders_Drinks with id 1 to equal 10.
It would be best if the command would update every record of the Orders_Drinks.
I know my database is not typical, but it is needed for my application. This is because the Drinks table is not needed for all entries. The Drinks table has over 5000 fields in it, so if every record had these details the database would grow and slow for no real reason. Please do not tell me to restructure the database, this is needed.
I am currently using for loops in my C# program to do what I need, but having 1 command would save a ton of time!
Here is my best attempt, but it gives an error of "invalid group function".
update Orders_Drinks join Items on Items.order_id=Orders_Drinks.id join Items_Drinks on Items_Drinks.id=Items.id set Orders_Drinks.drinks=sum(Item_Drinks.drinks);
I think this is what you're wanting.
Edited:
UPDATE `Order_Drinks` a
SET a.`drinks` = (SELECT SUM(b.`drinks`) FROM `Items_Drinks` b INNER JOIN `Items` c ON (b.`id` = c.`id`) WHERE a.`id` = c.`order_id`)
That should give you a total of 9 for the Order_Drinks table for the row id of 1.
This is assuming that Orders.id == Orders_Drinks.id and that Items.id == Items_Drinks.id.
You need to do an aggregation. You can do this in the join part of the update statement:
update Orders_Drinks od join
(select i.order_id, sum(id.drinks) as sumdrinks
from Items i join
Items_Drinks id
on id.id = i.id
) iid
on iid.order_id = od.id
set od.drinks = iid.sumdrinks;
Something like this will return the id from the orders_drinks table, along with the current value of the drinks summary field, and a new summary value derived from the related items_drinks tables.
(Absent the name of the foreign key column, I've assumed the foreign key column names are of the pattern: "referenced_table_id" )
SELECT od.id
, od.drinks AS old_drinks
, IFNULL(td.tot_drinks,0) AS new_drinks
FROM orders_drinks od
LEFT
JOIN ( SELECT di.orders_drinks_id
, SUM(di.drinks) AS tot_drinks
FROM items_drinks di
GROUP BY di.orders_drinks_id
) td
ON td.orders_drinks_id = od.id
Once we have SELECT query written that gets the result we want, we can change it into an UPDATE statement. Just replace SELECT ... FROM with the UPDATE keyword, and add a SET clause, to assign/replace the value to the drinks column.
e.g.
UPDATE orders_drinks od
LEFT
JOIN ( SELECT di.orders_drinks_id
, SUM(di.drinks) AS tot_drinks
FROM items_drinks di
GROUP BY di.orders_drinks_id
) td
ON td.orders_drinks_id = od.id
SET od.drinks = IFNULL(td.tot_drinks,0)
(NOTE: the IFNULL function is optional. I just used it to substitute a value of zero whenever there are no matching rows in items_drinks found, or whenever the total is NULL.)
This will update all rows (that need to be updated) in the orders_drinks table. A WHERE clause could be added (after the SET clause), if you only wanted to update particular rows in orders_drinks, rather than all rows:
WHERE od.id = 1
Again, to get to this, first get a SELECT statement working to return the new value to be assigned to the column, along with the key of the table to be updated. Once that is working, convert it into an UPDATE statement, moving the expression that returns the new value down to a SET clause.

MySQL INSERT INTO table 1 SELECT table 2 with different column name

I have a table (pdt_1) in database (db_1) and another table (pdt_2) in another database (db_2).
I met pdt_1 and pdt_2 to find pdt_1 products not present and published in pdt_2.
functional code :
SELECT * FROM db_1.pdt_1 AS lm
WHERE lm.product_sku
NOT IN (SELECT DISTINCT product_cip7 FROM db_2.pdt_2)
AND lm.product_publish=‘Y'
finally, I need to insert the result of this query in pdt_2.
However, the structure of pdt_1 and pdt_2 are different.
Example:
- columns's names
- columns's numbers
I also need an auto_increment id for pdt_1 products inserted into pdt_2.
I need help.
NB : sorry for my poor english :(
If you want a new table with just the id and product_sku, try:
INSERT INTO new_table # with id and product_sku from first table
SELECT pdt_1.id,
pdt_1.product_sku
FROM db_1.pdt_1
LEFT JOIN db_2.pdt_2
ON pdt_1.product_sku = pdt_2.product_cip7
WHERE pdt_2.product_cip7 IS NULL
AND pdt_1.product_publish = 'Y'

multiple query with sqlite 2nd query gives only first result

SELECT quantity, materialTypeId ,
(SELECT typeName
FROM invTypes
WHERE TypeID IN (SELECT materialTypeId
FROM invTypeMaterials
WHERE typeId= 12743
)
) AS material
FROM invTypeMaterials
WHERE TypeID=12743
so this query gives me nice results except the column material. only shows me the first entry instead of giving the name of each row.
if i run these sql seperate they work and i do see what i want. i just need them combined into 2 columns.
what i want to do is, i query one table for data, one of the column has a value wich i want to convert to a name, and that is in another table and its linked by a unique TypeID
Chilly
May be this will work :
SELECT tm.quantity, tm.materialTypeId , t.typeName
FROM invTypeMaterials tm
INNER JOIN invTypes t ON t.TypeID = tm.materialTypeId
WHERE tm.TypeID=12743
If you want to lookup the materialTypeID's name for the current record, you must not use a separate subquery but use the materialTypeID value from the outer query.
This is called a correlated subquery:
SELECT quantity, materialTypeId,
(SELECT typeName
FROM invTypes
WHERE TypeID = invTypeMaterials.materialTypeId
) AS material
FROM invTypeMaterials
WHERE TypeID=12743

sql query for deleting rows with NOT IN using 2 columns

I have a table with a composite key composed of 2 columns, say Name and ID. I have some service that gets me the keys (name, id combination) of the rows to keep, the rest i need to delete. If it was with only 1 row , I could use
delete from table_name where name not in (list_of_valid_names)
but how do I make the query so that I can say something like
name not in (valid_names) and id not in(valid_ids)
// this wont work since they separately dont identity a unique record or will it?
Use mysql's special "multiple value" in syntax:
delete from table_name
where (name, id) not in (select name, id from some_table where some_condition);
If your list is a literal list, you can still use this approach:
delete from table_name
where (name, id) not in (select 'john', 1 union select 'sally', 2);
Actually, no I retract my comment about needing special juice or being stuck with (AND OR'ing all your options).
Since you have a list of values of what you want to retain, dump that into a temporary table. Then do a delete against the base table for what does not exist in the temporary table (left outer join). I suck at mysql syntax or I'd cobble together your query. Psuedocode is approximate
DELETE
B
FROM
BASE B
LEFT OUTER JOIN
#RETAIN R
ON R.key1 = B.key1
AND R.key2 = B.key
WHERE
R.key1 IS NULL
The NOT EXISTS version:
DELETE
b
FROM
BaseTable b
WHERE
NOT EXISTS
( SELECT
*
FROM
RetainTable r
WHERE
(r.key1, r.key2) = (b.key1, b.key2)
)