mysql: Get combination of data from multiple table by passing multiple value - mysql

In my DB. I have three tables Category, Location and classification.
I have some value in array for every column
location:['delhi','mumbai','goa','chennai']
Category:['Teacher','Student','Managment']
classification:['expert','normal']
Now I want to fetch the combination of data from the table.
I'm using a stored procedure for this.
Previously I have only one location, one category and one classification so I'm using this:
FROM user u1, serviceprovider s1, city c1
WHERE s1.userId = u1.id
AND c1.cityId = s1.city
AND s1.serviceProviderId IN
(SELECT DISTINCT serviceprovidecategoryr_cl AS serviceProviderId
FROM Db.serviceprovider_cl__serviceproviderclassification_classification t1
INNER JOIN Db.location_servicelocation__serviceprovider_locationid t2 ON t1.serviceprovider_cl = t2.serviceprovider_locationId
INNER JOIN Db.category_serviceprovidercategory__serviceprovider_category t3 ON t2.serviceprovider_locationId = t3.serviceprovider_category
WHERE
t1.serviceproviderclassification_classification IN
(SELECT serviceProviderClassificationId
FROM serviceProviderClassification sp
WHERE sp.name = classification)
AND t2.location_serviceLocation IN
(SELECT locationId
FROM location
WHERE shortAddress = location)
AND t3.category_serviceProviderCategory IN
(SELECT categoryId
FROM category
WHERE categoryName = category)
);
END
but now I'm getting the multiple values so how to modify this stored procedure?
If there is any other good way for doing this.
Please help...

Related

Complex how to update one DB/Table with data from a different DB/Table

I need to populate a new field in an existing table. While at it I want to check and update several of the other fields based on the same source table.
The source is in a table from a different data base with over 1.4 million entries. The target table has about 9,000 entries. My goal is to update the following fields in the target table: 'fccid, city, state, zip' with the current source values. The common field is 'callsign' in both the source and target tables. The issue being the row 'callsign' has multiple entries in the source table and only one in the target. The largest 'fccid' value in source is the correct one to use.
The code below extracts from the source table values I want to update in the target table. But I do not understand how to update the target table with this information for just the records in the target table. Do I need to create a temp file from the output of the source code, and use it for the update code? This would still be a very large table, how do I do the update directly?
Source Code:
SELECT b.callsign, a.fccid, a.city, a.state, a.zip
FROM fcc_amateur.en a
INNER JOIN (
SELECT callsign, MAX(fccid) fccid
FROM fcc_amateur.en
GROUP BY callsign ) b
ON a.callsign = b.callsign AND a.fccid = b.fccid
;
Target Code:
UPDATE stations SET
fccid = b.fccid,
city = a.city, state = a. state, zip = a.zip
WHERE a.callsign = b.callsign
;
You can embed JOIN operations among those 3 tables directly inside the UPDATE statement:
UPDATE stations s
INNER JOIN (SELECT callsign, MAX(fccid) AS fccid
FROM fcc_amateur.en
GROUP BY callsign) b
ON s.callsign = b.callsign
INNER JOIN fcc_amateur.en a
ON a.callsign = b.callsign AND a.fccid = b.fccid
SET fccid = b.fccid,
city = a.city,
state = a.state,
zip = a.zip
In MySQL 8.0, a slightly better performing way of getting your last "fccid" value from your "fcc_amateur.en" table is using the ROW_NUMBER window function, that assigns a ranking value (1, 2, 3, ...) to each "fccid" value in a specified partition (your "callsign"). Once you have that, you can select all first descendently callsign values by filtering them (WHERE ranking = 1).
UPDATE stations s
INNER JOIN (SELECT callsign, fccid,
ROW_NUMBER() OVER(PARTITION BY callsign ORDER BY fccid DESC) AS rn
FROM fcc_amateur.en
GROUP BY callsign) b
ON s.callsign = b.callsign
INNER JOIN fcc_amateur.en a
ON a.callsign = b.callsign AND a.fccid = b.fccid
SET fccid = b.fccid,
city = a.city,
state = a.state,
zip = a.zip
WHERE b.rn = 1

SQL select rows that have one value but not another

I have a table in SQL which will contain multiple rows for one id, as below
accountid Productname
1 GL
1 IP
1 MI
2 GL
2 IP
2 PA
3 MI
3 CP
3 IP
4 GL
4 CP
4 CI
I want to be able to select all accounts which have certain products but not other. For example all that have IP or GL but not MI, using the sample table above this would return accounts 2 and 4.
SELECT ccx_accountidname
FROM (
SELECT ccx_accountidname, ccx_productname
FROM Filteredccx_leadresearch
WHERE ccx_productname IN ('GL','IP')
AND ccx_accountidname IS NOT NULL
) AS T
WHERE ccx_productname NOT IN ('MI')
ORDER BY ccx_accountidname
and
SELECT DISTINCT LR1.ccx_accountidname
FROM Filteredccx_leadresearch LR1
LEFT JOIN Filteredccx_leadresearch LR2 ON LR1.ccx_accountid = LR2.ccx_accountid
AND LR2.ccx_productname IN ('GL', 'IP')
WHERE LR1.ccx_productname NOT IN ('MI')
AND LR1.ccx_accountidname IS NOT NULL
ORDER BY LR1.ccx_accountidname
Both give basically the same results, is there any way this can be done?
Thanks in advance for any help
Could you try this:
SELECT DISTINCT T1.Accountidname FROM TheTableThatContainsAccountnames as T1
JOIN AccountProductsTable as T2 on T1.AccountId=T2.AccountId
WHERE T2.ProductName = 'ProductYouWant'
AND T2.ProductName = 'AnOtherProductYouWant'
According to your post, all you really need is a simple query with the correct and logic. You want all accounts with Product name GL or IP but not in MI. This will do it without any other joins.
SELECT ccx_accountidname
FROM Filteredccx_leadresearch
WHERE
ccx_productname in ('GL','IP')
and ccx_productname not in ('MI')
EDIT
This will get you the account, though I doubt it will work in your overall solution. It's just hard to tell without seeing your complete dataset. This could be done with parameters too.
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable
IF OBJECT_ID('tempdb..#TempTableTwo') IS NOT NULL
DROP TABLE #TempTableTwo
create table #TempTable (accountid int, productname char(2))
insert into #TempTable (accountid,productname) values
(1,'GL'),
(1,'IP'),
(1,'MI'),
(2,'GL'),
(2,'IP'),
(2,'MA')
select distinct
t1.accountid,
1 as T
into #TempTableTwo
from
#TempTable t1
where
productname in ('GL','IP')
union all
select distinct
t1.accountid,
-1 as T
from
#TempTable t1
where
productname in ('MI')
select
accountid
from #TempTableTwo
group by accountid
having sum(T) > 0
I might be late for the game, but this should do the trick, if anyone is trying to solve a similar problem. I renamed your table and it's columns:
Filteredccx_leadresearch -> l_search
ccx_accountidname -> a_name
ccx_productname -> p_name
And here's the SQL:
(SELECT DISTINCT t1.a_name
FROM l_search t1
JOIN l_search t2 ON t1.a_name = t2.a_name
WHERE t1.p_name = 'IP'
OR t2.p_name = 'GL')
MINUS
(SELECT DISTINCT t1.a_name
FROM l_search t1
JOIN l_search t2 ON t1.a_name = t2.a_name
WHERE ((t1.p_name = 'IP'OR t1.p_name = 'GL') AND t2.p_name = 'MI')
OR
(t1.p_name = 'MI' AND (t1.p_name = 'IP' OR t1.p_name = 'GL')));
First set:
cross product of table on itself with same IDs, get account IDs which have a product 'IP' or 'GL'.
Second set:
cross product of table on itself with same IDs, get account IDs which have p_name ('IP' OR 'GL') on first cross property AND 'MI' on second.
Also, get those IDs, which have the same but the other way around: p_name 'MI' on first cross property AND ('IP' OR 'GL') on second.
And finally subtract the second from the first.
Here is a simple way to include the accounts that match either IP or GL and exclude those accounts if they have an record for MI without using a subquery.
This is assuming t1 is a table that has unique account numbers in accountid and t2 is the table you have shown above that has accountid and Productname columns.
SELECT DISTINCT
t1.accountid
FROM t1
LEFT JOIN t2 AS t2_match
ON t1.accountid = t2_match.accountid
AND
(
t2_match.Productname = 'IP'
OR t2_match.Productname = 'GL'
)
LEFT JOIN t2 AS t2_not_match
ON t1.accountid = t2_not_match.accountid
AND t2_not_match.Productname = 'MI'
WHERE
t2_match.accountid IS NOT NULL
AND t2_not_match.accountid IS NULL
This is really late, but it might help some one.
I'll focus only on using the columns we have on the table we are shown (won't combine it with other tables we were not given).
Since the only table in the example is not clearly named, I'll call it some_table
SELECT t.accountidname, t.productname
FROM some_table t
WHERE t.productname IN ('GL','IP')
AND t.accountidname NOT IN (
SELECT accountidname
FROM some_table
WHERE productname = 'MI'
);
The idea here is to:
Select all accountid and productname that have productname either GL or IP (3rd line)
Select all accountid that have a productname MI and remove them from the values we already have (4th line onwards)
With this values, filtering or combining it with other tables should be rather trivial.
You might want to replace the SELECT with SELECT DISTINCT if the combinations of accountid and productname could be repeated in the table.

(another) LEFT JOIN issue with ACCESS

I want summary data from my 'Data' table for all companies in 'Companies' table including blank rows where there is no record in Data.
If I summarise the data in a nested SELECT clause (or in a stored query i get nothing from the data table. For example
This is the sub select
SELECT transco,
sum(m1) AS Jan15,
FROM data
WHERE (QVmeasure = 'Vol')
GROUP BY QVmeasure, transco
which outputs:
transco Jan15
0292 154373665
1419 134915098
If I use it in a sub select as follows
SELECT c.SAP_Code,
Jan15
FROM Companies AS c
LEFT JOIN (
SELECT transco,
sum(m1) as Jan15
FROM data
WHERE (QVmeasure = 'Vol')
GROUP BY QVmeasure, transco)
AS d
ON c.SAP_Code = d.transco
I get:
SAP_Code Jan15
0292
1419
I can get the correct result via a temporary table:
SELECT sum(m1) as Jan15,
transco
INTO Temp_Table
FROM data
WHERE (QVmeasure = 'Vol')
GROUP BY QVmeasure, transco
followed by
Select c.SAP_code,
jan15
FROM companies AS c
LEFT JOIN Temp_Table as i
ON (c.SAP_Code = i.transco)
giving:
SAP_code jan15
0292 154373665
1419 134915098
1423
but if I use temporary tables I will have to create macros and i want users to be able to run just a query.
The following works for this simple case but I can't apply it in other circumstances:
SELECT c.SAP_Code,
sum(m1) AS Jan15
FROM Companies AS c
LEFT JOIN data as d
ON c.SAP_Code = d.transco
WHERE (d.QVmeasure = 'Vol') OR (d.QVmeasure is null)
GROUP BY d.QVmeasure,c.sap_code
Is there something wrong with my sub select syntax or is it ACCESS (2013)
TIA
You could nest the sub-query like this:
SELECT c.SAP_Code,
(SELECT sum(d.m1)
FROM data AS d
WHERE d.QVmeasure = 'Vol' AND c.SAP_Code = d.transco
) AS [Jan15]
FROM Companies AS c

How to search where some data is in table 1 and other data is in table 3 with both having a UUID the same

I have 3 tables
For instance
Salestable
-ID
-variableB
-customerUUID
-variableC
Customertable
-customerUUID
-contractUUID
Contracttable
-contractUUID
-variableD
So I am currently doing a SQL Query on salestable
Like:
SELECT DISTINCT variableB FROM Salestable WHERE variableD = "blah";
How can I do this? Where I can find the contract associated with the current salestable?
A bit more info
They are all a 1:1 relationship - so Contracttable is tied to 1 Customertable which is tied to 1 salestable
There is a LOT of data in my database thousands of entries - this query does not run constantly but does need to run somewhat efficent.
SELECT a.*
FROM SalesTable a
INNER JOIN CustomerTable b
ON a.customerUUID = b.customerUUID
INNER JOIN Contracttable c
ON b.contractUUID = c.contractUUID
WHERE c.variableD = 'valueHere'
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
If you sure the contract exists use this (othewise swap INNER FOR LEFT):
SELECT variableB, variableD
FROM Salestable t1
INNER JOIN Customertable t2 ON (t1.customerUUID = t2.customerUUID)
INNER JOIN Contracttable t3 ON (t3.contractUUID = t2.contractUUID)
WHERE variableD = "blah"
GROUP BY t1.variableB

How do i deal with this situation for searching records in mysql?

i am developing a PHP/MYSQL search module, where i have to search tables based on many different criteria, i have some 11 tables, and i have used multiple joins to create one single MySQL query and based on WHERE clause i intend to search for specific records, here is the MYSQL Query that i am using.
SELECT
prop.id,
prop.serial,
prop.title,
prop.rating,
prop.addDate,
prop.approve,
prop.status,
prop.user_id as userId,
user_det.email as email,
user_det.name as name,
prop.area_id as areaId,
area.name as areaName,
area.zipCode as zipCode,
area.city_id as cityId,
city.name as cityName,
city.state_id as stateId,
state.name as stateName,
state.country_id as countryId,
country.name as countryName,
prop.subCategory_id as subCategoryId,
subCat.name as subCategoryName,
subCat.category_id as categoryId,
cat.name as categoryName,
prop.transaction_id as transactionId,
trans.name as transactionName,
price.area as landArea,
price.price as priceSqFt,
price.total_price as totalPrice,
features.bedroom,
features.bathroom,
features.balcony,
features.furnished,
features.floorNum,
features.totalFloor
FROM properties prop
LEFT JOIN user_details user_det ON (prop.user_id = user_det.user_id)
LEFT JOIN areas area ON (prop.area_id = area.id)
LEFT JOIN cities city ON (area.city_id = city.id)
LEFT JOIN states state ON (city.state_id = state.id)
LEFT JOIN countries country ON (state.country_id = country.id)
LEFT JOIN subCategories subCat ON (prop.subCategory_id = subCat.id)
LEFT JOIN categories cat ON (subCat.category_id = cat.id)
LEFT JOIN transactions trans ON (prop.transaction_id = trans.id)
LEFT JOIN prop_prices price ON (price.property_id = prop.id)
LEFT JOIN prop_features features ON (features.property_id = prop.id)
although all works well here, i have a situation where i have a table called prop_amenities below are the content of this table.
as the table above have multiple property_id if i query it using JOINS then mostly it will return duplicate records or single record omitting others depending on the type of JOIN i use. so instead i would like to deal it this way.
use the table prop_amenities to only deal with conditions not to return the result.
for example i am searching for a property with amenity id 1,5,9,17 and 24, then it should check if all the records exist in the prop_amenities table, i.e 1,5,9,17 and 24 in this case. and return the appropriate records with all above selected columns.
i am clueless on dealing this situation using MySQL. how do i go on this?
thank you..
You said "check if all the records exist in the prop_amenities table" and that's the key word here.
SELECT ...
FROM properties AS prop
LEFT JOIN ...
WHERE EXISTS (SELECT 1 FROM prop_amenities AS pa WHERE pa.property_id = prop.property_id AND pa.amenity_id = 7);