I have database with ERD:
And sample data:
CREATE TABLE `AppUser` (
`AppUser_ID` bigint(20) NOT NULL,
`SomeFields` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`AppUser_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
INSERT INTO `AppUser` (`AppUser_ID`, `SomeFields`) VALUES
(1, 'values'),
(2, 'values'),
(3, 'values'),
(4, 'values'),
(5, 'values');
CREATE TABLE `IdpUser` (
`IdpUser_ID` bigint(20) NOT NULL,
`SomeFields` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL,
ADD PRIMARY KEY (`IdpUser_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
INSERT INTO `IdpUser` (`IdpUser_ID`, `SomeFields`) VALUES
(1, 'values'),
(2, 'values'),
(3, 'values'),
(4, 'values'),
(5, 'values');
CREATE TABLE `UserClaim` (
`Attribute_ID` bigint(20) NOT NULL,
`IdpUser_ID` bigint(20) DEFAULT NULL,
`AttributeKey` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL,
`AttributeValue` bigint(20) DEFAULT NULL,
PRIMARY KEY (`Attribute_ID`),
FOREIGN KEY (`IdpUser_ID`) REFERENCES `IdpUser` (`IdpUser_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
INSERT INTO `UserClaim` (`Attribute_ID`, `IdpUser_ID`, `AttributeKey`, `AttributeValue`) VALUES
(1, 1, 'Email_ID', 1),
(2, 2, 'Email_ID', 2),
(3, 3, 'Email_ID', 3),
(4, 4, 'Email_ID', 4),
(5, 5, 'Email_ID', 5),
(6, 2, 'Phone_ID', 4),
(7, 3, 'Phone_ID', 2),
(8, 4, 'Phone_ID', 3),
(9, 5, 'Phone_ID', 5),
(10, 2, 'PublicKey_ID', 1),
(11, 3, 'PublicKey_ID', 2),
(12, 1, 'PublicKey_ID', 1);
CREATE TABLE `UserInfo` (
`Attribute_ID` bigint(20) NOT NULL,
`AppUser_ID` bigint(20) DEFAULT NULL,
`AttributeKey` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL,
`AttributeValue` bigint(20) DEFAULT NULL,
PRIMARY KEY (`Attribute_ID`),
FOREIGN KEY (`AppUser_ID`) REFERENCES `AppUser` (`AppUser_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
INSERT INTO `UserInfo` (`Attribute_ID`, `AppUser_ID`, `AttributeKey`, `AttributeValue`) VALUES
(1, 1, 'Email_ID', 1),
(2, 2, 'Email_ID', 2),
(3, 3, 'Email_ID', 3),
(4, 4, 'Email_ID', 4),
(5, 5, 'Email_ID', 2),
(6, 2, 'Phone_ID', 1),
(7, 3, 'Phone_ID', 2),
(8, 4, 'Phone_ID', 3),
(9, 5, 'Phone_ID', 4);
CREATE TABLE `UserMapping` (
`Mapping_ID` int(11) NOT NULL,
`AppUser_ID` bigint(20) NOT NULL,
`IdpUser_ID` bigint(20) NOT NULL,
PRIMARY KEY (`Mapping_ID`),
FOREIGN KEY (`AppUser_ID`) REFERENCES `AppUser` (`AppUser_ID`),
FOREIGN KEY (`IdpUser_ID`) REFERENCES `IdpUser` (`IdpUser_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
INSERT INTO `UserMapping` (`Mapping_ID`, `AppUser_ID`, `IdpUser_ID`) VALUES
(1, 2, 2),
(2, 3, 3),
(3, 1, 1),
(4, 4, 5),
(5, 5, 4);
UserInfo holds internal User info, UserClaim holds external User info, my application has multiple login type. Internal User and External User is mapped.
I use both internal and external User attribute for mapping Users to a Customer. If Users have the same AttributeKey and AttributeValue will be grouped in a Customer and the following attributes of those Users must be added to the Customer
All User with the same AttributeKey and AttributeValue is
grouped into a group.
The Customer will have all attribute of the Users belong to that Customer.
For example - with above data we have Mapping_ID = 2 belongs to Customer1 with list of attributes :
Email_ID = [2]
Phone_ID = [1,4]
PublicKey_ID = [1]
And we also have Mapping_ID = 5 with list of attributes:
Email_ID = [2,5]
Phone_ID = [4,5]
PublicKey_ID = []
And we also have Mapping_ID = 1 with list of attributes:
Email_ID = [1]
Phone_ID = []
PublicKey_ID = [1]
Because Email_ID = 2, Phone_ID = 4 belong to Mapping_ID = [2,5] so Mapping_ID = [2,5] is mapped to Customer1.
Because PublicKey_ID = 1 belong to Mapping_ID = [2,1] so Mapping_ID = [2,1] is mapped to Customer1.
=> Mapping_ID = [1,2,5] are mapped to Customer1 and Customer1 attributes :
Email_ID = [1,2,5]
Phone_ID = [1,4,5]
PublicKey_ID = [1]
My approach is to group by AttributeKey and AttributeValue in each UserInfo and UserClaim to get temporary Customers and their attributes, then join their attributes together and group to a Customer with the same AttributeKey and AttributeValue. I saw my approach made thing difficult to intersect list of attributes to group the Customer and how to store Customer attributes for effectively add or remove attributes.
I am looking for an idea for this problem or any better approach to solve this puzzle.
UserInfo has approximately 100m rows.
UserClaim has approximately 300m rows.
I can use MySql, PDI (Pentaho Data Integration) tools to design and maintain ETL to get my result.
Related
I have to write a command that uses the following database:
CREATE TABLE `autori` (
`idAutor` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`numeAutor` varchar(255) NOT NULL
);
INSERT INTO `autori` (`idAutor`, `numeAutor`) VALUES
(1, 'Ion Creanga'),
(2, 'Walter Scott'),
(3, 'Mihai Eminescu'),
(4, 'George Bacovia'),
(5, 'William Shakespeare'),
(6, 'Agatha Christie'),
(7, 'Jules Verne');
CREATE TABLE `edituri` (
`idEditura` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`numeEditura` varchar(255) NOT NULL
);
INSERT INTO `edituri` (`idEditura`, `numeEditura`) VALUES
(1, 'Litera'),
(2, 'CARTEA ROMANEASCA'),
(3, 'MONDORO'),
(4, 'RAO'),
(5, 'PENGUIN BOOKS'),
(6, 'Paralela 45'),
(7, 'CASA EDITORIALA DEMIURG PLUS');
CREATE TABLE `carti` (
`idCarte` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`titluCarte` varchar(255) NOT NULL,
`idAutor` mediumint(8) UNSIGNED NOT NULL,
`nrPagini` smallint(5) UNSIGNED DEFAULT NULL,
`ISBN` varchar(17) NOT NULL,
`anPublicare` year(4) DEFAULT NULL,
`idEditura` smallint(5) UNSIGNED NOT NULL,
`stoc` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
`refExterna` varchar(255) DEFAULT NULL,
UNIQUE KEY `isbnUnic` (`ISBN`),
FOREIGN KEY (`idAutor`) REFERENCES `autori` (`idAutor`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`idEditura`) REFERENCES `edituri` (`idEditura`) ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO `carti` (`idCarte`, `titluCarte`, `idAutor`, `nrPagini`, `ISBN`, `anPublicare`, `idEditura`, `stoc`, `refExterna`) VALUES
(1, 'Amintiri din copilarie', 1, 48, '978-9975-74-380-8', 2014, 1, 5, NULL),
(2, 'Steaua Sudului', 7, 239, '978-973-23-3185-9', 2017, 2, 2, NULL),
(3, 'Sarpele de mare', 7, 199, '978-973-23-3184-2', 2017, 2, 1, NULL),
(4, '20.000 de leghe sub mari', 7, 300, '978-606-695-008-4', 2014, 3, 9, NULL),
(5, 'Crima din Orient Express', 6, 247, '978-606-609-620-1', 2017, 4, 20, NULL),
(6, 'Poirot investigheaza', 6, 217, '978-606-609-277-7', 2012, 4, 1, NULL),
(7, 'Journey to the Centre of the Earth', 7, 254, '978-0-14-062425-0', 1994, 5, 15, NULL),
(8, 'Cele mai frumoase povesti si povestiri', 1, 211, '978-973-47-2074-3', 2015, 6, 64, NULL),
(9, 'Poezii', 3, 382, '978-606-8395-85-2', 2014, 3, 32, NULL),
(10, 'Hamlet', 5, 228, '978-973-152-006-3', 2007, 7, 13, NULL);
CREATE TABLE `tipuriUtilizatori` (
`idTipUtilizator` tinyint(3) UNSIGNED NOT NULL,
`numeTip` varchar(255) NOT NULL
);
INSERT INTO `tipuriUtilizatori` (`idTipUtilizator`, `numeTip`) VALUES
(1, 'Necunoscut'),
(2, 'Bibliotecar'),
(3, 'Student');
CREATE TABLE `utilizatori` (
`idUtilizator` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`numeUtilizator` varchar(255) NOT NULL,
`idTipUtilizator` tinyint(3) UNSIGNED NOT NULL
);
INSERT INTO `utilizatori` (`idUtilizator`, `numeUtilizator`, `idTipUtilizator`) VALUES
(1, 'Xulescu', 3),
(2, 'Ygrec', 3),
(3, 'Zet', 0),
(4, 'Q', 2);
CREATE TABLE `imprumuturi` (
`idUtilizator` int(10) UNSIGNED NOT NULL,
`idCarte` int(10) UNSIGNED NOT NULL,
UNIQUE (`idUtilizator`,`idCarte`),
FOREIGN KEY (`idUtilizator`) REFERENCES `utilizatori` (`idUtilizator`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`idCarte`) REFERENCES `carti` (`idCarte`) ON DELETE CASCADE ON UPDATE CASCADE
) ;
INSERT INTO `imprumuturi` (`idUtilizator`, `idCarte`) VALUES
(2, 3),
(3, 4),
(1, 5);
My command needs to return titluCarte, numeAutor, numeEditura, and also to subtract the rows of imprumuturi table from carti.stoc. I have managed to write this, but the subtracting doesn't return 162-3. What am I doing wrong?
SELECT titlucarte,
numeautor,
numeeditura,
stoc
FROM carti
JOIN autori
ON ( carti.idautor = autori.idautor )
JOIN edituri
ON ( carti.ideditura = edituri.ideditura )
UNION
SELECT '--------------------------------------',
'--------',
'--------',
'----'
UNION
SELECT 'total carti',
'--------',
'--------',
Sum(stoc)
FROM carti
UNION
SELECT '--------------------------------------',
'--------',
'--------',
'----'
UNION
SELECT 'carti disponibile',
'--------',
'--------',
Sum(carti.stoc) - (SELECT Count(*)
FROM imprumuturi)
FROM imprumuturi,
carti;
Every other things works well, my problem is with the subtraction from the end of the command.
If you want 159 change your last select query to below.
SELECT 'carti disponibile',
'--------',
'--------',
Sum(carti.stoc) - (SELECT Count(*) FROM imprumuturi)
FROM carti;
DEMO
The reason you get garbage value in the stoc column is because of the 14th line in your above code. Its expecting a number but you are changing the datatype to string and hence the garbage values.
Try changing ----- to a number like 0 for example and you should get the desired output
See below on sql fiddle
http://sqlfiddle.com/#!9/25e5a1/17
SELECT titlucarte,
numeautor,
numeeditura,
stoc
FROM carti
JOIN autori
ON ( carti.idautor = autori.idautor )
JOIN edituri
ON ( carti.ideditura = edituri.ideditura )
UNION
SELECT '--------------------------------------' as 'titlucarte',
'--------' as 'numeautor',
'--------' as 'numeeditura',
/*'----' as 'stoc' */ /*code removed*/
0 as stoc /* code added*/
UNION
SELECT 'total carti' as 'titlucarte',
'--------' as 'numeautor',
'--------' as 'numeeditura' ,
Sum(stoc) as 'stoc'
FROM carti
UNION
SELECT '--------------------------------------' as 'titlucarte',
'--------' as 'numeautor',
'--------' as 'numeeditura' ,
'----' as 'stoc'
UNION
SELECT 'carti disponibile' as 'titlucarte',
'--------' as 'numeautor',
'--------' as 'numeeditura' ,
Sum(carti.stoc) - (SELECT Count(*)
FROM imprumuturi) as 'stoc'
FROM /*imprumuturi,*/
carti;
I am learning MySQL and I currently do not understand how to do something.
I have two tables and I want to display some stuff out of it, it's pretty hard to explain so I'd rather show you.
These are my tables:
CREATE TABLE IF NOT EXISTS `proprietate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`serie_buletin` varchar(8) NOT NULL,
`cnp` bigint(20) NOT NULL,
`nr_vehicul` int(11) NOT NULL,
`data_cumpararii` date NOT NULL,
`pret` int(11) NOT NULL,
`id_persoana` int(11) NOT NULL,
PRIMARY KEY (id),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
CREATE TABLE IF NOT EXISTS `vehicul` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nr_vehicul` int(11) NOT NULL,
`marca` varchar(30) NOT NULL,
`id_marca` int(11) NOT NULL,
`tip` varchar(15) NOT NULL,
`culoare` varchar(15) NOT NULL,
`capacitate_cilindrica` int(11) NOT NULL,
`id_proprietate` int(11) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id_proprietate) REFERENCES proprietate(id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
And these are my values inside my tables:
INSERT INTO `proprietate` (`id`, `serie_buletin`, `cnp`, `nr_vehicul`, `data_cumpararii`, `pret`, `id_persoana`) VALUES
(1, 'AK162332', 2006036035087, 4, '2014-05-01', 35000, 1),
(2, 'AK162332', 2006036035087, 10, '2014-05-02', 90000, 2),
(3, 'AK176233', 6548751520125, 2, '2014-05-03', 55000, 3),
(4, 'BZ257743', 6548751520125, 2, '2014-05-04', 25000, 4),
(5, 'BZ257743', 2006036035087, 15, '2014-05-05', 63000, 5),
(6, 'DC456542', 2003564784513, 7, '2014-05-06', 30000, 6),
(7, 'EN654872', 2012654879521, 6, '2014-05-07', 50000, 7);
INSERT INTO `vehicul` (`id`, `nr_vehicul`, `marca`, `id_marca`, `tip`, `culoare`, `capacitate_cilindrica`, `id_proprietate`) VALUES
(1, 4, 'Mercedes', 1, 'CLK 350', 'negru', 3500, 1),
(2, 10, 'Mercedes', 1, 'S 500', 'silver', 5000, 2),
(3, 2, 'Mercedes', 1, 'ML 550', 'alb', 5500, 3),
(4, 2, 'BMW', 2, '325', 'galben', 2500, 4),
(5, 15, 'BMW', 2, 'X5', 'negru', 3500, 5),
(6, 7, 'Audi', 3, 'R5', 'mov', 5000, 6),
(7, 6, 'Audi', 3, 'Q5', 'metalic', 3000, 7);
What I want to display is:
marca | nr_vehicul | average_price
Audi | 13 | 40000
BMW | 17 | 44000
Mercedes | 16 | 60000
How can I do that? So far I have managed to display the first two columns but I have no idea how to reference the first table in the second and calculate the average price.
This is what I have so far:
SELECT marca, SUM(nr_vehicul) AS nr_vehicul FROM vehicul GROUP BY marca
Can anyone help me please?
You should join your tables to get combined information from both of them:
SELECT marca, SUM(vehicul.nr_vehicul) AS nr_vehicul, avg(pret) as pret
FROM vehicul
LEFT OUTER JOIN proprietate on (id_proprietate = proprietate.id)
GROUP BY marca;
see this sql fiddle session for the output.
First you select the data (column names with appropriate functions used) you need: marca, SUM(vehicul.nr_vehicul), AVG(pret), then you construct the joined structure from where mysql should retrieve these informations: vehicul, proprietate.
For this structure you need primarily the vehicul table, by which you will group the result set. You want to join the proprietate table to the vehicul table properly, to make sure the correct data structure is created. Since you have foreign key from one table to the other, the easiest way to do it is to use that key: LEFT OUTER JOIN proprietate on (id_proprietate = proprietate.id).
For more information on understanding the different JOIN types, please see this article by Craig Buckler.
$query = "SELECT type, AVG(pret) FROM vehicul GROUP BY marca";
$result = mysql_query($query) or die(mysql_error());
// Print out result
while($row = mysql_fetch_array($result)){
echo "The average price of ". $row['type']. " is $".$row['AVG(price)'];}</code>
should return the average price per marca
So I'm looking to provide a category (x) style product count on my website.
I'm currently using MySQL.
My categories table looks like:
Categories (Id, TreeLeft, TreeRight, Level, Name) - with 'Level' being the node depth.
Categories entered look like this:
My Item > Categories relation table looks like:
ItemCategories (ItemId, CategoryId)
Assuming I have:
1 item under 'TUBE'
2 items under 'LCD'
1 item under 'FLASH'
1 item under '2 WAY-RADIOs'
How can I most efficiently query my items (large db) + categories (4000 in db), to produce:
Electronics (5)
- Televisions (3)
- Tube (1)
- LCD (2)
- Portable Electronics (2)
- MP3 Players (1)
- Flash (1)
- 2 Way Radios (1)
Taking note to only return those categories which have products in them and also correctly counts them up the tree.
Any help most appreciated.
Edit: DB Code to recreate environment locally:
CREATE TABLE IF NOT EXISTS `Categories` (
`Id` int(11) NOT NULL auto_increment,
`TreeLeft` mediumint(7) NOT NULL,
`TreeRight` mediumint(7) NOT NULL,
`Level` tinyint(3) NOT NULL,
`Name` varchar(255) NOT NULL,
UNIQUE KEY `Id` (`Id`),
KEY `TreeLeft` (`TreeLeft`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;
INSERT INTO `Categories` (`Id`, `TreeLeft`, `TreeRight`, `Level`, `Name`) VALUES
(1, 1, 20, 1, 'Electronics'),
(2, 2, 9, 2, 'Television'),
(3, 10, 19, 2, 'Portable Electronics'),
(4, 3, 4, 3, 'Tube'),
(5, 5, 6, 3, 'LCD'),
(6, 7, 8, 3, 'Plasma'),
(7, 11, 14, 3, 'MP3 Players'),
(8, 15, 16, 3, 'CD Players'),
(9, 11, 14, 3, '2 Way Radios'),
(10, 12, 13, 4, 'Flash');
CREATE TABLE IF NOT EXISTS `ItemCategories` (
`CategoryId` int(11) NOT NULL,
`ItemId` int(11) NOT NULL,
KEY `CategoryId` (`CategoryId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `ItemCategories` (`CategoryId`, `ItemId`) VALUES
(4, 3442),
(5, 3441),
(5, 3456),
(9, 5343),
(10, 5423);
Please see the subsection, entitled Aggregate Functions in a Nested Set, of Mike Hillyer's classic article on this subject at Managing Hierarchical Data in MySQL
I wish to divide values from the same column using mySQL.
is there a better way of doing this??? Do I really need 3 select statements?
SELECT (SELECT FixAM From Fixes WHERE Id = 1) / (SELECT FixAM From Fixes WHERE Id = 2)
My table structure is as follows:
CREATE TABLE IF NOT EXISTS `Fixes` (
`Id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'PK',
`CurrencyId` int(11) NOT NULL COMMENT 'FK',
`MetalId` int(11) NOT NULL COMMENT 'FK',
`FixAM` decimal(10,5) NOT NULL,
`FixPM` decimal(10,5) DEFAULT NULL,
`TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`Id`),
KEY `CurrencyId` (`CurrencyId`),
KEY `MetalId` (`MetalId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=13 ;
--
-- Dumping data for table `Fixes`
--
INSERT INTO `Fixes` (`Id`, `CurrencyId`, `MetalId`, `FixAM`, `FixPM`, `TimeStamp`) VALUES
(1, 1, 1, '1592.50000', '1586.25000', '2013-02-25 15:10:21'),
(2, 2, 1, '1051.84900', '1049.59300', '2013-02-25 15:10:21'),
(3, 3, 1, '1201.88700', '1194.10600', '2013-02-25 15:10:21'),
(4, 1, 2, '29.17000', NULL, '2013-02-25 13:54:02'),
(5, 2, 2, '19.27580', NULL, '2013-02-25 13:54:02'),
(6, 3, 2, '21.98190', NULL, '2013-02-25 13:54:02'),
(7, 1, 3, '1627.00000', '1620.00000', '2013-02-25 14:28:59'),
(8, 2, 3, '1074.65000', '1072.50000', '2013-02-25 14:28:59'),
(9, 3, 3, '1229.30000', '1218.95000', '2013-02-25 14:28:59'),
(10, 1, 4, '747.00000', '748.00000', '2013-02-25 14:28:59'),
(11, 2, 4, '493.40000', '495.20000', '2013-02-25 14:28:59'),
(12, 3, 4, '564.40000', '562.85000', '2013-02-25 14:28:59');
I think this is what you're looking for:
SELECT MetalId,
MAX(CASE WHEN CurrencyId = 1 THEN FixAM END) /
MAX(CASE WHEN CurrencyId = 2 THEN FixAM ELSE 1 END) Output
FROM Fixes
GROUP BY MetalId
This produces 1592.50000 / 1051.849000. If you want the opposite, swap the currency ids.
SQL Fiddle Demo
In case you don't have a CurrencyId = 2, I defaulted the dividing value to 1 so you wouldn't receive an error.
Following is a dump of the tables and data needed to answer understand the system:-
The system consists of tutors and classes.
The data in the table All_Tag_Relations stores tag relations for each tutor registered and each class created by a tutor. The tag relations are used for searching classes.
CREATE TABLE IF NOT EXISTS `Tags` (
`id_tag` int(10) unsigned NOT NULL auto_increment,
`tag` varchar(255) default NULL,
PRIMARY KEY (`id_tag`),
UNIQUE KEY `tag` (`tag`),
KEY `id_tag` (`id_tag`),
KEY `tag_2` (`tag`),
KEY `tag_3` (`tag`),
KEY `tag_4` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `Tags` (`id_tag`, `tag`) VALUES
(1, 'Sandeepan'),
(2, 'Nath'),
(3, 'first'),
(4, 'class'),
(5, 'new'),
(6, 'Bob'),
(7, 'Cratchit');
CREATE TABLE IF NOT EXISTS `All_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0',
`id_tutor` int(10) default NULL,
`id_wc` int(10) unsigned default NULL,
KEY `All_Tag_Relations_FKIndex1` (`id_tag`),
KEY `id_wc` (`id_wc`),
KEY `id_tag` (`id_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `All_Tag_Relations` (`id_tag`, `id_tutor`, `id_wc`) VALUES
(1, 1, NULL),
(2, 1, NULL),
(3, 1, 1),
(4, 1, 1),
(6, 2, NULL),
(7, 2, NULL),
(5, 2, 2),
(4, 2, 2),
(8, 1, 3),
(9, 1, 3);
Following is my query:-
This query searches for "first class" (tag for first = 3 and for class = 4, in Tags table) and returns all those classes such that both the terms first and class are present in the class name.
SELECT wtagrels.id_wc,SUM(DISTINCT( wtagrels.id_tag =3)) AS
key_1_total_matches,
SUM(DISTINCT( wtagrels.id_tag =4)) AS
key_2_total_matches
FROM all_tag_relations AS wtagrels
WHERE ( wtagrels.id_tag =3
OR wtagrels.id_tag =4 )
GROUP BY wtagrels.id_wc
HAVING key_1_total_matches = 1
AND key_2_total_matches = 1
LIMIT 0, 20
And it returns the class with id_wc = 1.
But, I want the search to show all those classes such that all the search terms are present in the class name or its tutor name
So that searching "Sandeepan class" (wtagrels.id_tag = 1,4) or "Sandeepan Nath" also returns the class with id_wc=1. And Searching. Searching "Bob First" should not return any classes.
Please modify the above query or suggest a new query, if possible using MyIsam - fulltext search, but somehow help me get the result.
I think this query would help you:
SET #tag1 = 1, #tag2 = 4; -- Setting some user variables to see where the ids go. (you can put the values in the query)
SELECT wtagrels.id_wc,
SUM(DISTINCT( wtagrels.id_tag =#tag1 OR wtagrels.id_tutor =#tag1)) AS key_1_total_matches,
SUM(DISTINCT( wtagrels.id_tag =#tag2 OR wtagrels.id_tutor =#tag2)) AS key_2_total_matches
FROM all_tag_relations AS wtagrels
WHERE ( wtagrels.id_tag =#tag1 OR wtagrels.id_tag =#tag2 )
GROUP BY wtagrels.id_wc
HAVING key_1_total_matches = 1 AND key_2_total_matches = 1
LIMIT 0, 20
It returns id_wc = 1.
For (6, 3) the query returns nothing.