I have a table (netStream), that has 2 foreign keys: (logSessions_logSessionID) and (accountSessions_accountSessionID).
The (logSessions_logSessionID) is mandatory the (accountSessions_accountSessionID) is NOT mandatory.
Here is the part of the block-scheme that shows the connections and the non-mandatory status:
(The background: logSessions are the sessions that every visitor have, accountSessions are the login sessions. Everybody has a logSession (since everybody is a visitor), but not everybody is logged in, so they do not have accountSession)
I want to insert a row into (netStream), in every case there is a (logSession), but it is not the same with (accountSession). So, when there is an (accountSession), I want to insert that ID too, if there is no (accountSession), then just leave that field in (netStream) NULL.
The hash values are stored in Binary(x), this is why I use UNHEX().
This is the MySQL I wrote, there is no error message, but it does not work. What is the problem?
INSERT INTO `test-db`.`netStream` (`netStreamHash`, `logSessions_logSessionID`, `accountSessions_accountSessionID`)
SELECT UNHEX("1faab"), `logSessions`.`logSessionID`, NULL FROM `logSessions` CROSS JOIN `accountSessions`
WHERE `logSessions`.`logSessionHash` = UNHEX("aac") AND
`accountSessions`.`accountSessionHash` = UNHEX("2fb");
If understand you correctly you are probably looking for something like this
INSERT INTO `test-db`.`netStream` (
`netStreamHash`,
`logSessions_logSessionID`,
`accountSessions_accountSessionID`)
SELECT UNHEX("1faab"),
(SELECT `logSessionID` FROM `logSessions`
WHERE `logSessionHash` = UNHEX("aac")),
(SELECT `accountSessionID` FROM `accountSessions`
WHERE `accountSessionHash` = UNHEX("2fb"));
If there is no matching row in accountSessions then you'll get NULL inserted in accountSessions_accountSessionID in netStream table
Related
So i'm trying to select unread messages with a query, but the results are blank. I need to get the info from a seperate table read so it will know it was read or not. Im trying to do something like a IF statement so if readed not exists it will be unread, but i can't get it fixed
this is my query:
SELECT * FROM notify
INNER JOIN readed ON readed.acc_ID = '26' AND readed.user_ID = '6'
AND readed.msg_ID = notify.ID AND readed.readed != '1' OR readed.ID IS NULL
WHERE notify.groep = '1'
DB - readed
ID - int
user_ID - int
acc_ID - int
msg_ID - int
readed - enum ('0','1')
DB - notify
ID - int
notfi - text
thumb_src - text
title - text
url - text
groep - int
I hope someone know whats the problem!
The query seems correct to me, except the part with the OR, so I suppose that the problem is with the data. I will first try to show how you could improve the query nevertheless, and then try to show how to debug your data.
First, let's leave away the OR condition since this won't work as expected in a JOIN ON clause.
Second, when comparing integer fields to values, you should not put quotes around the values. This will only worry every person who tries to understand the query because the quotes denote string values, and it will worry (i.e. slow down) MySQL's parser, because it must convert the string values to numbers.
Third, mixing up normal WHERE conditions and JOIN ON conditions is worrying and bad style (IMHO). I always recommend to put only the conditions which actually link the tables into the JOIN ON clause, and other conditions elsewhere.
Following this advice would lead to something like that:
SELECT * FROM
notify INNER JOIN readed ON
readed.msg_ID = notify.ID
WHERE
readed.acc_ID = 26 AND
readed.user_ID = 6 AND
readed.readed != '1' AND
notify.groep = 1
This should do the same as your original query minus the OR part.
Now, since we suspect that there is a problem with the data, we can begin to debug the data. First, leave away the WHERE clause:
SELECT * FROM
notify INNER JOIN readed ON
readed.msg_ID = notify.ID
If this returns data, then you at least know that there are rows in the readed table matching rows in the notify table. If it does not return any data, then there are no rows which fit together, and have found the root of your problem.
Provided that the above returns data, re-add the WHERE clause line by line and test after each step. For example, start with
SELECT * FROM
notify INNER JOIN readed ON
readed.msg_ID = notify.ID
WHERE
readed.acc_ID = 26 AND
and continue with
SELECT * FROM
notify INNER JOIN readed ON
readed.msg_ID = notify.ID
WHERE
readed.acc_ID = 26 AND
readed.user_ID = 6 AND
and so on, testing the query each time.
That way, you hopefully will find out where the problem is. I am convinced that the problem is with the data, not with the query.
This is my first time creating a MySQL stored procedure and am stuck on getting the UPDATE piece to work correctly. The proc is performing an inner join, looking for matches on a domain name field. If there is a match, a column named inbound is getting updated with a value of 0. If there is not a match on the join, then I need inbound set to a value of 1.
When I run this, I am able to get the matches tagged with a 0, but the non-matches are not getting updated with a 1. I thought how I have the 'ELSE' part set up would take care of this- can anyone tell if I am missing something with the syntax?
CREATE PROCEDURE `sp_InboungTagging`()
BEGIN
update `tableA` a
inner join `TableD` d
on a.senderDomain = d.domainName
set inbound = CASE
when a.senderDomain = d.domainName then 0
ELSE 1
END
WHERE inbound is null;
END;|
DELIMITER ;
Thanks,
Ron
EDIT-
Thanks for your reply. I am looking for exact matches on a varchar field that has domain names in it- the master list of domains is in table D. If the record in TableA has a match in TableD, I want to tag that recored with a 0. If there is no match in TableD, then I would like to tag it with a 1. Let me know if that clears things up- thanks
Your JOIN condition is the same as your CASE condition. If you JOIN your two tables on:
a.senderDomain = d.domainName
Then there will be no values in the result set for which
a.senderDomain != d.domainName
so the ELSE clause of your CASE statement never fires.
Without knowing more about what you mean by "matches" and "non-matches," I can't really suggest a correction.
I am importing data to a table structured: content_id|user_id|count - all integers all comprise the composite primary key
The table I want to select it from is structured: content_id|user_id
For reasons quite specific to my use case, I will need to fire quite a lot of data into this regularly enough to want a pure MySQL solution
insert into new_db.table
select content_id,user_id,xxx from old_db.table
I want each row to go in with xxx set to 0, unless this would create a duplicate key, in which case I wish to increment the number, for the current user_id/content_id combination
Not being a MySQL expert, I tried a few options like trying to populate xxx by selecting from the target table during insert, with no luck. Also tried using ON DUPLICATE KEY to increment counters instead of the usual UPDATE. But it all seemed a bit daft so I thought I would come here!
Any ideas anyone? I have a backup option of wrapping this in PHP, but it would drastically raise the overall running time of the script in which this would be the only non-pure MySQL part
Any help really appreciated. thanks in advance!
--edit
this may sound really awful in principle. but id settle for a way to do it in an update after entering random numbers (i have sent in random numbers to allow me to continue other work at the moment) - and this is a purely dev setup
--edit again
12|234
51|45
51|45
51|45
23|67
would ideally insert
12|234|0
51|45|0
51|45|1
51|45|2
23|67|0
INSERT INTO new_db.table (content_id, user_id, cnt)
SELECT old.content_id, old.user_id, COUNT(old.*) - 1 FROM old_db.table old
GROUP BY old.content_id, old.user_id
this would be the way I would go, so if 1 entry it would put 0 on cnt, for more it would just put 1-2-3 etc.
Edit:
Your correct answer would be somewhat complicated but I tested it and it works:
INSERT INTO newtable(user_id,content_id,cnt)
SELECT o1.user_id, o1.content_id,
CASE
WHEN COALESCE(#rownum, 0) = 0
THEN #rownum:=c-1
ELSE #rownum:=#rownum-1
END as cnt
FROM
(SELECT user_id, content_id, COUNT(*) as c FROM oldtable
GROUP BY user_id, content_id ) as grpd
LEFT JOIN
(SELECT oldtable.* FROM oldtable) o1 ON
(o1.user_id = grpd.user_id AND o1.content_id = grpd.content_id)
;
Assuming that in the old db table (source), you will not have the same (content_id, user_id) combination, then you can import using this query
insert newdbtable
select o.content_id, o.user_id, ifnull(max(n.`count`),-1)+1
from olddbtable o
left join newdbtable n on n.content_id=o.content_id and n.user_id=o.user_id
group by o.content_id, o.user_id;
Ran into a bit of trouble when trying to insert records into my DB from my forum
What it does when you create a thread is make an entry into 2 tables. First the forum_threads table with information on the thread title, description, poster, post time, etc. It will use thread_id with AUTO_INTEGER to generate the threads ID.
I then need to get that thread_id from the forum_threads and then put that as the thread_id in the forum_posts table.
I'm not sure if theres anyway I can select a row based on its ID after I just inserted it. Would I just have to select the most recent ID? Would that leave a margin of error? Other thought I had was to select based on user name and post time.
Thoughts?
<?php
if (isset($_POST['submit'])) {
$thread_sql = "
INSERT INTO forum_threads (
user_id,
forum_id,
thread_postdate,
thread_title,
thread_description,
thread_icon
) VALUES (
'$_SESSION[user_id]',
'$_GET[f]',
'$date',
'$_POST[topictitle]',
'$_POST[topicdescription]',
'$_POST[posticon]'
)
";
$thread_query = #mysqli_query ($db_connect, $thread_sql);
$post_sql = "
INSERT INTO forum_posts (
user_id,
thread_id,
post_message,
post_date
) VALUES (
'$_SESSION[user_id]',
'',
'$_POST[content]',
'$date'
)
";
$post_query = #mysqli_query ($db_connect, $post_sql);
}
?>
To first answer your question directly, the function mysql_insert_id() will return the ID that was assigned to the most recently inserted row. There's no guesswork involved; MySQL will happily tell you (through its own built-in LAST_INSERT_ID() function) what ID it assigned.
On a separate note, I see that you're directly inserting values from $_POST into your SQL statement. Never, ever, EVER do that. This exposes your application to SQL injection attacks.
Either use the mysql_real_escape_string() function to properly escape the values for use in a SQL statement, or, since you're already using mysqli_ functions, use placeholders (? values) to create a prepared statement.
MySqli_Insert_Id () will return the last auto generated ID. Call this function immediately after you insert your new thread.
INSERT
INTO forum_threads (…)
VALUES (…)
INSERT
INTO forum_posts (thread_id, …)
VALUES (LAST_INSERT_ID(), …)
You can just use the last_insert_id to get the ID of the row you just inserted; don't worry about anybody else inserting a row just after, the last_insert_id is per-connection, so unless they used your connection, you're safe.
There is an API-level call to retrieve this so you don't need to ask the server specifically.
Oh yes, also, do not use the # operator in PHP, ever, google for it if you want to know why it's bad.
Use MySQL's last_insert_id() function in sql code or the php wrapper for it mysql_insert_id() in a php script. These will give you the last auto_increment number generated in your connection. So it's thread safe.
I'm a bit embarassed asking this here, but here goes:
I've got two tables, which you can see here:
http://img411.imageshack.us/img411/4562/query.jpg
I need to copy the effortid from the one table into the other, making sure that the values still maintain the correction relationships. The primary key for each is a combination of loggerid & datetime. What's the best way to do this?
Thanks in advance, and don't make fun :)
Change it to an Update Query instead. The joins should function correctly, but will not add missing rows. To do that, you would use an Append Query, like you have setup, but with a left join and a check for nulls. The sample below updates the LogID table with information residing in LogSiteID table.
Append Missing Records from Logger Site ID to LogID
INSERT INTO logID ( [Datetime], loggerid, temp, effortid )
SELECT ls.datetime, ls.loggerid, ls.temp, ls.effortid
FROM logID AS l RIGHT JOIN [Logger Site ID] AS ls ON (l.temp = ls.temp) AND (l.loggerid = ls.loggerid) AND (l.Datetime = ls.datetime)
WHERE (((l.loggerid) Is Null));
Update effortids from Logger Site ID to LogID
UPDATE logID AS l INNER JOIN [Logger Site ID] AS ls ON (l.Datetime = ls.datetime) AND (l.temp = ls.temp) AND (l.loggerid = ls.loggerid) SET l.effortid = [ls].[effortid];