Related
The problem:
When I update Tom in the redo table, I want the changes to affect the daily and lab irrespective of whether Tom exists in daily or lab. Even if he doesn't exist in daily or
lab I want the update to be made only in the redo table.
Look at the tables below:
First table redo
Second Table daily
Third Table lab
What I tried:
UPDATE redo,daily,lab SET
redo.name = '$newName', daily.name = '$newName', lab.name = '$newName',
redo.place = '$newPlace', daily.place = '$newPlace', lab.place = '$newPlace',
redo.code = '$newCode', daily.code = '$newCode', lab.code = '$newCode',
redo.age = '$newAge', daily.age= '$newAge', lab.age = '$newAge',
redo.date = redo.date, daily.date = daily.date, lab.date = lab.date,
redo.contact = '$newContact',daily.contact = '$newContact', lab.contact='$newContact',
redo.secondarycontact = '$newSecondaryContact',
daily.secondarycontact = '$newSecondaryContact',
lab.secondarycontact = '$newSecondaryContact'
WHERE redo.no='$no' AND
(redo.name=daily.name AND redo.name=lab.name) AND
(redo.place=daily.place AND redo.place=lab.place)
Result:
Values are updated only if they exist in all the 3 tables at the same time.
Given your use case and relationships, this is how I would set up the tables if it were my project:
NOTE:
I've made some assumptions about your field types in the below that may not be correct, but it should be trivial to adapt them as needed for your use case.
Using this structure will require slightly more complex or well thought out queries, but the result will be MUCH more maintainable and far less error prone.
I would normaly name columns and such differently, but I've elected to use names similar to the naming convention you seem to be using to keep it simple since this question isnt about "best practices naming columns" etc..
Create the tables
Create an 'activities' table to hold all types of activities in one place, note the "type" column with possible values of 'lab','redo','daily'
CREATE TABLE `activities` (
`no` bigint(20) NOT NULL AUTO_INCREMENT,
`consultation` varchar(255) DEFAULT NULL,
`lab` varchar(255) DEFAULT NULL,
`token` VARCHAR(45) NULL,
`detailsid` bigint(20) NOT NULL,
`foreignkey` bigint(20) DEFAULT NULL,
`type` enum('lab','redo','daily') NOT NULL,
`date` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`no`)
);
Create an 'activitiyusers' table to hold the details for the people that are related to our "activities"
CREATE TABLE `activitiyusers` (
`no` BIGINT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`gender` ENUM('M', 'F') NOT NULL,
`age` SMALLINT NULL,
`contact` VARCHAR(255) NOT NULL,
`secondarycontact` VARCHAR(255) NULL,
`place` VARCHAR(255) NULL,
`code` VARCHAR(45) NULL,
`createdat` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
`updatedat` VARCHAR(45) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`no`));
Insert some test data
Insert 3 new "activitiyusers"
INSERT INTO `activitiyusers` (`name`, `gender`, `age`, `contact`, `secondarycontact`, `place`, `code`) VALUES ('Tom', 'M', '31', '1212121', '3434343', 'California', '1');
INSERT INTO `activitiyusers` (`name`, `gender`, `age`, `contact`, `secondarycontact`, `place`, `code`) VALUES ('Jack', 'M', '45', '99999', '11111', 'Colorado', '2');
INSERT INTO `activitiyusers` (`name`, `gender`, `age`, `contact`, `secondarycontact`, `place`, `code`) VALUES ('Harry', 'M', '99', '112233', '998877', 'Texas', '3');
Insert 3 new "redo" activities, one related to each of our 3 "activitiyusers"
INSERT INTO `activities` (`token`, `detailsid`, `foreignkey`, `type`) VALUES ('0', '1', NULL, 'redo');
INSERT INTO `activities` (`token`, `detailsid`, `foreignkey`, `type`) VALUES ('0', '2', NULL, 'redo');
INSERT INTO `activities` (`token`, `detailsid`, `foreignkey`, `type`) VALUES ('0', '3', NULL, 'redo');
Insert 2 new "daily" activities, one related to Tom and 'redo' activity 1, the second related to Harry and 'redo' activity 3"
INSERT INTO `activities` (`consultation`, `detailsid`, `foreignkey`, `type`) VALUES ('Cough and Cold', '1', '1', 'daily');
INSERT INTO `activities` (`consultation`, `detailsid`, `foreignkey`, `type`) VALUES ('Panadol', '3', '3', 'daily');
Insert 2 new "lab" activities, one related to Jack and 'redo' activity 2, the second related to Harry and 'redo' activity 3"
INSERT INTO `activities` (`lab`, `detailsid`, `foreignkey`, `type`) VALUES ('Blood Test', '2', '2', 'lab');
INSERT INTO `activities` (`lab`, `detailsid`, `foreignkey`, `type`) VALUES ('Injection', '3', '3', 'lab');
Examples of how to work with this data:
Note: these queries will make use of join cluases as well as Column and table aliases
Get All "activities" for "Tom", along with Tom's details
SELECT
a.no AS activityno,
a.consultation,
a.lab,
a.token,
a.type,
a.date,
au.no AS userno,
au.name,
au.gender,
au.age,
au.contact,
au.secondarycontact,
au.place,
au.code,
au.createdat,
au.updatedate
FROM
activities a
JOIN
activitiyusers au ON a.detailsid = au.no
WHERE
name = 'Tom';
Get all "redo type activities" for "Jack", along with Jack's details
SELECT
a.no AS activityno,
a.consultation,
a.lab,
a.token,
a.type,
a.date,
au.no AS userno,
au.name,
au.gender,
au.age,
au.contact,
au.secondarycontact,
au.place,
au.code,
au.createdat,
au.updatedate
FROM
activities a
JOIN
activitiyusers au ON a.detailsid = au.no
WHERE
name = 'Jack' AND a.type = 'redo';
# Given a known activity that has an id/no of '2',
# update the details for the activityuser related to that activity
UPDATE activitiyusers
SET
contact = '22222222',
age = 46,
code = 5
WHERE
no = (SELECT
detailsid
FROM
activities
WHERE
no = 2);
Given a known "repo" activity that has an id/no of '3', get all sub activities related to that activity along with details of the related activitiyuser
Note that this utilizes a mysql self join, ie we are joining the activities on itself to get subActivity rows that are related to a given redoActivity row.
SELECT
redoActivity.no AS redoactivityno,
subActivity.no AS subactivityno,
redoActivity.consultation AS redoactivityconsultation,
subActivity.consultation AS subactivityconsultation,
subActivity.lab,
redoActivity.token,
subActivity.type,
redoActivity.date AS redoactivitydate,
subActivity.date AS subactivitydate,
au.no AS userno,
au.name,
au.gender,
au.age,
au.contact,
au.secondarycontact,
au.place,
au.code,
au.createdat,
au.updatedate
FROM
activities subActivity
JOIN activities redoActivity ON subActivity.foreignkey = redoActivity.no
JOIN activitiyusers au ON redoActivity.detailsid = au.no
WHERE
redoActivity.no = 3;
I have a data from GPS tracker.
Let's say something like:
CREATE TABLE IF NOT EXISTS `gps_data` (
`id` int(6) unsigned NOT NULL,
`speed` int(3) unsigned NOT NULL,
`time` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
and some sample data:
INSERT INTO `gps_data` (`id`, `speed`, `time`) VALUES
('1', '5', '07:00'),
('2', '10', '07:10'),
('3', '0', '07:20'),
('4', '0', '07:30'),
('5', '0', '07:40'),
('6', '0', '07:50'),
('7', '20', '08:00'),
('8', '40', '08:10'),
('9', '15', '08:15'),
('10', '0', '08:32'),
('11', '0', '08:40'),
('12', '0', '08:52'),
('13', '12', '09:10'),
('14', '0', '09:25');
The question is how to find a time of first and last position with speed = 0.
So in my example I would like to have something like:
[break_start, break_stop]
[07:20, 07:50]
[08:32, 08:52]
[09:25, NULL]
Here is the Fiddle to better understanding: http://sqlfiddle.com/#!9/d79228/4
What I have started to try is:
SELECT `time` AS break_start, `time` AS break_stop FROM `gps_data` WHERE `speed`=0;
One method in MySQL is to assign a group to each row. This group can be the number of non-zero values before the row -- all rows with adjacent zero values are in the same group.
In MySQL 8+, you can use window functions for this:
select min(time), max(time)
from (select t.*,
sum(speed <> 0) over (order by time) as grp
from t
) t
where speed = 0
group by grp;
In earlier versions, one method is a correlated subquery:
select min(time), max(time)
from (select t.*,
(select count(*)
from t t2
where t2.speed <> 0 and t2.time <= t.time
) as grp
from t
) t
where speed = 0
group by grp;
Here is a SQL Fiddle.
I want to get count of post subscribed by user below is my table schema , please help me with query for the same, i trie many option but could not do it
I tried and was able to get post count of user below is my query , but here i have used static user id , i want single query to list count for all users
SELECT COUNT(*)
FROM CATMAPPING INNER JOIN
POST ON CATMAPPING.pid = POST.id
where FIND_IN_SET(CATMAPPING.cid,(select selectedcatid from subscribers where id='1'));
Desire OP
Desired Output
uemail Postcount
-----------------------------
a#s.com 4
b#s.com 8
c#s.com 10
d#s.com 4
SQL fiddel link : http://sqlfiddle.com/#!9/4fff8f/2
CREATE TABLE subscribers (
`id` int(10),
`uemail` varchar(255) DEFAULT NULL,
`selectedcatid` varchar(255) DEFAULT NULL
) ;
ALTER TABLE subscribers ADD PRIMARY KEY (`id`);
ALTER TABLE subscribers MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT;
INSERT INTO subscribers (`uemail`, `selectedcatid`) VALUES ('a#s.com', '1'),
('b#s.com', '1,3'),
('c#s.com', '1,2,3'),
('d#s.com', '3');
CREATE TABLE POST (
`id` int(10),
`title` varchar(255) DEFAULT NULL
) ;
INSERT INTO POST (`id`, `title`) VALUES ('1', 'ABC'),
('2', 'DEF'),
('3', 'GHI'),
('4', 'JKL'),
('5', 'MNO'),
('6', 'PQR'),
('7', 'STU'),
('8', 'VXZ'),
('9', 'ASO'),
('10', 'LMO');
CREATE TABLE CATMAPPING (
`cid` int(10),
`pid` int(10) DEFAULT NULL
) ;
INSERT INTO CATMAPPING (`pid`, `cid`) VALUES ('1', '1'),
('2', '2'),
('3', '3'),
('4', '1'),
('5', '2'),
('6', '3'),
('7', '3'),
('8', '3'),
('9', '1'),
('10', '1');
Here is the correct query I wrote in sql server may be some syntax is diffrent but it gives me correct result I creates a table valued function and then used it for the query .
declare #tempsub as table (subid int,selectcatId int )
insert into #tempsub
select id ,string
from subscribers
CROSS APPLY [dbo].[ufn_CSVToTable] (selectedcatid)
--select * from #tempsub
-- subid is the id of the subscribes table
SELECT subid , count(*) from post p inner join CATMAPPING c on c.pid = p.id
left join #tempsub t on t.selectcatId= c.cid
group by t.subid
-- below is the code for tabled valued function it return a table for comma seprated string
create FUNCTION dbo.[ufn_CSVToTable] ( #StringInput VARCHAR(8000) )
RETURNS #OutputTable TABLE ( [String] nVARCHAR(1000) )
AS
BEGIN
DECLARE #String nVARCHAR(1000)
WHILE LEN(#StringInput) > 0
BEGIN
SET #String = LEFT(#StringInput,
ISNULL(NULLIF(CHARINDEX(',', #StringInput) - 1, -1),
LEN(#StringInput)))
SET #StringInput = SUBSTRING(#StringInput,
ISNULL(NULLIF(CHARINDEX(',', #StringInput), 0),
LEN(#StringInput)) + 1, LEN(#StringInput))
INSERT INTO #OutputTable ( [String] )
VALUES ( #String )
END
RETURN
END
How can I 'score' results using order by, if possible, by number of matches between a given user and every other user in a table.
Basically, I have a given 'userid' of '1' and I need to check all of this users 'interests' against of users interests and order by the number of like matches between users.
Say userid '1' has 4 interests in common with userid '4', but only 3 interests in common with userid '2', it would return 4 first, then 2, then everyone else with less overall interest matches.
I have tried about 10 different queries to no avail, not even one that was close, which is why I didn't post any of the attempts here.
CREATE TABLE `interests` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`userid` int(12) NOT NULL DEFAULT '0',
`interest` varchar(100) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `interests` set `userid` = '1', `interest` = 'term1';
INSERT INTO `interests` set `userid` = '1', `interest` = 'term2';
INSERT INTO `interests` set `userid` = '1', `interest` = 'term3';
INSERT INTO `interests` set `userid` = '1', `interest` = 'term4';
INSERT INTO `interests` set `userid` = '2', `interest` = 'term1';
INSERT INTO `interests` set `userid` = '2', `interest` = 'term2';
INSERT INTO `interests` set `userid` = '2', `interest` = 'term8';
INSERT INTO `interests` set `userid` = '2', `interest` = 'term4';
INSERT INTO `interests` set `userid` = '3', `interest` = 'term9';
INSERT INTO `interests` set `userid` = '3', `interest` = 'term2';
INSERT INTO `interests` set `userid` = '3', `interest` = 'term3';
INSERT INTO `interests` set `userid` = '3', `interest` = 'term7';
INSERT INTO `interests` set `userid` = '4', `interest` = 'term1';
INSERT INTO `interests` set `userid` = '4', `interest` = 'term2';
INSERT INTO `interests` set `userid` = '4', `interest` = 'term3';
INSERT INTO `interests` set `userid` = '4', `interest` = 'term4';
The proper result set should look like:
-------
userid
-------
4
2
3
Any help here is greatly appreciated guys.
You can do a SELF JOIN:
SELECT i2.userid
FROM interests i1
INNER JOIN interests i2
ON i2.userid <> i1.userid
AND i2.interest = i1.interest
WHERE i1.userid = 1
GROUP BY i2.userid
ORDER BY COUNT(*) DESC;
ONLINE DEMO
The easiest way is to get a list of all users and shares and counts and then select and order the ones you want from that sub-query. It makes the logic clear:
SELECT userid, otherid, sameCount
FROM (
SELECT base.userid, other.userid as otherid, count(*) sameCount
FROM interests base
JOIN interests other ON base.interest = other.interest and base.userid != other.userid
GROUP BY base.userid, other.userid
) sub
WHERE userid = 1
ORDER BY sameCount DESC
This query should do it
select i.userid, count(i2.userid) countInterests
from interests i
inner join interests i2 on i.interest = i2.interest and i.Id <> i2.id
group by i.userid, i2.userid
order by userid, count(i2.userid) desc
I have a small business and I made a simple mysql database for entering Client name, Datetime, Details, Invoice, Signer, Billing total, Month to date, Year to date, Parts purchased, Parts Purchased year to date. I would like to automatically update the dollar amounts, is this possible? For example: Month to date is $1300.00 the next
entry is for $100.00 leaving a total of $1400.00.
Any help would be greatly appreciated.
You'll want to store your information in such a way that it is accurate and efficient. Then use queries to pull the information you are looking for for month to date and year to date.
Lets create a test database and a few tables. You can add columns as needed.
Test database
CREATE DATABASE stackoverflow;
USE stackoverflow;
Create the table for clients
This will store all your clients
CREATE TABLE clients (
client_id INT NOT NULL PRIMARY KEY auto_increment,
client_name VARCHAR( 70 ) NOT NULL,
client_details TEXT
) engine = myisam DEFAULT charset=latin1;
Create the table for parts
This will store all the parts that you wish to invoice client for
CREATE TABLE parts (
part_id INT NOT NULL PRIMARY KEY auto_increment,
part_name VARCHAR( 70 ) NOT NULL,
part_cost NUMERIC( 15,2 ),
description TEXT
) engine = myisam DEFAULT charset=latin1;
Create the table for invoices
This will store each invoice that is created. Notice that there is no dollar values or parts here. Doing it this way will reduce the number of times that identical information has to be stored.
Database normalization is the process of organizing the attributes and tables of a relational database to minimize data redundancy. Wikipedia
CREATE TABLE invoices (
invoice_id INT NOT NULL PRIMARY KEY auto_increment,
client_id INT NOT NULL,
invoice_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
details TEXT,
signer VARCHAR ( 70 ) NOT NULL
) engine = myisam DEFAULT charset=latin1;
Create table to connect parts to invoices
Now, lets create a table that will connect our parts table with the invoices. Here we can add information like the notes and quantity that is unique to each item for each invoice. We will use the quantity in our queries to calculate our totals, MTD, YTD, etc.
CREATE TABLE invoice_parts (
id INT NOT NULL PRIMARY KEY auto_increment,
part_id INT NOT NULL,
invoice_id INT NOT NULL,
quantity INT NOT NULL,
notes TEXT
) engine = myisam DEFAULT charset=latin1;
Lets add some test information
-- add some clients
INSERT INTO `clients` (`client_id`, `client_name`, `client_details`) VALUES (NULL, 'chad barker', 'some guy named chad'), (NULL, 'leon tester', 'some guy named leon');
-- add some parts
INSERT INTO `parts` (`part_id`, `part_name`, `part_cost`, `description`) VALUES (NULL, 'can of awesome', '1.99', 'awesome can of awesome'), (NULL, 'can of fail', '.25', 'can filled with failure'), (NULL, 'box of blocks', '24.99', 'box full of cube shaped items called blocks'), (NULL, 'bag of air', '3.99', 'reusable bag filled with useless air');
-- add some invoices
INSERT INTO `invoices` (`invoice_id`, `client_id`, `invoice_date`, `details`, `signer`) VALUES (NULL, '1', CURRENT_TIMESTAMP, 'there was an order for some stuff', ''), (NULL, '1', CURRENT_TIMESTAMP, 'more stuff needed now', ''), (NULL, '2', CURRENT_TIMESTAMP, 'need some stuff quick', ''), (NULL, '2', CURRENT_TIMESTAMP, 'don''t ship, just charge me', '');
-- add some invoice/part connections
INSERT INTO `invoice_parts` (`part_id`, `invoice_id`, `quantity`, `notes`) VALUES ('3', '1', '3', 'nothing special'), ('2', '1', '2', 'wants blue'), ('4', '2', '32', 'wants every color'), ('3', '2', '31', 'wants clear'), ('2', '3', '12', 'wants blue'), ('1', '4', '2', 'wants every color'), ('1', '1', '3', 'nothing special'), ('2', '1', '2', 'wants blue'), ('3', '2', '22', 'wants every color'), ('4', '2', '3', 'wants clear'), ('2', '3', '12', 'wants blue'), ('3', '4', '2', 'wants every color');
Query the invoice information
SELECT
c.client_name,
i.invoice_date,
i.details,
i.signer
FROM invoices i
INNER JOIN clients c
ON i.client_id = c.client_id
WHERE i.invoice_id = 1
;
Query the list of parts
SELECT
ip.invoice_id,
p.part_id,
p.part_name,
p.part_cost,
ip.quantity,
p.part_cost * ip.quantity as total
FROM invoice_parts ip
INNER JOIN parts p
ON ip.part_id = p.part_id
WHERE ip.invoice_id = 1;
Query the total cost of an invoice
SELECT
ip.invoice_id,
SUM( p.part_cost * ip.quantity ) as invoice_total
FROM invoice_parts ip
INNER JOIN parts p
ON ip.part_id = p.part_id
WHERE ip.invoice_id = 1;
Query by a selected month
SELECT
month( i.invoice_date ) as month,
count( distinct ip.invoice_id ) as invoices,
count( * ) as parts,
p.part_cost * ip.quantity as total
FROM invoices i
INNER JOIN invoice_parts ip
ON ip.invoice_id = i.invoice_id
INNER JOIN parts p
ON ip.part_id = p.part_id
WHERE i.client_id = 2
AND month( i.invoice_date ) = 5;
Query by a selected year
SELECT
year( i.invoice_date ) as year,
count( distinct ip.invoice_id ) as invoices,
count( * ) as parts,
p.part_cost * ip.quantity as total
FROM invoices i
INNER JOIN invoice_parts ip
ON ip.invoice_id = i.invoice_id
INNER JOIN parts p
ON ip.part_id = p.part_id
WHERE i.client_id = 1
AND year( i.invoice_date ) = 2014;