I have the following database structure:
And the data stored inside is as follows:
However, I like to select data from this database in the following format:
How can I use one single SELECT statement to achieve this? If using one single SELECT statement cannot, how to achieve this by whatever sql code? Can someone give me the implementation?
Can I use one single SELECT statement to achieve this?
Yes, you can. You will have to play a little with JOIN and GROUP BY statement, but it can be achieved.
EDIT:
Let's try multiple JOIN statements:
Select sum.name, x0.y_value, x10.y_value, x20.y_value
from test_summary as sum
join test_details as x0 on sum.id=x0.id and x0.x_value=0
join test_details as x10 on sum.id=x10.id and x10.x_value=10
join test_details as x20 on sum.id=x20.id and x20.x_value=20
Based on answers to multiple joins and join with where clause
The things you like called pivot table, and this is out of scope of relation data base system like mySQL. So there many special platforms for OLAP. But if you do not need any comprehensive OLAP things, but produce some pivot tables using mySQL and PHP you do not need any special sql, but nedd to program such presentation by php, may be using some commercial frameworks like this or some opensource code
Related
I'm currently thinking about a database schema in MySQL where I store SELECT queries into a certain table column, just to execute them on-the-fly when getting selected, and having the result passed instead of the actual query.
Would this be possible somehow? Or may this be bad practice? Is it even technically possible to have a result table passed to a single field, at least so I could run the query through PDO to get back a nested result array? Are there any alternatives?
I've read that this may be achieved through stored procedures, and although I grip the concept of those I can't think of how I could use those to achieve that.
You could do this, but what purpose do you have for doing it?
I would suggest using views:
The syntax should be valid when the view is created, unlike storing
the SQL in a field which may have invalid syntax.
It's easier to debug and modify.
For example, let's say one of the queries you want to store is:
SELECT product_category, COUNT(*) AS category_count
FROM product
GROUP BY product_category;
You can create a new "view" object that defines this query:
CREATE VIEW prod_cat_count AS
SELECT product_category, COUNT(*) AS category_count
FROM product
GROUP BY product_category;
Now, the object called "prod_cat_count" is stored in the database. Internally, the database just knows that "prod_cat_count" is equal to the SELECT query we mentioned. When the view is created, the database validates the syntax (checks that all columns exist, checks you haven't forgotten the GROUP BY, for example)
Then, whenever you want to get this data/run this query, you can run this statement (in SQL or in application code, for example):
SELECT product_category, category_count
FROM prod_cat_count;
If you then decide you want to change the way the product categories are counted, you can adjust the view:
SELECT product_category, COUNT(*) AS category_count
FROM product
GROUP BY product_category
ORDER BY product_category;
Hope that helps!
It is a bad habbit to use select "*" when writing SQL with JDBC.
But what if there are many columns in the table(s), how can I easily pickup some wanted columns in the SQL rather than using *?
For example,suppose I have table1 and table2,which have 10 columns each. I need most of their columns, but I do not want to use SELECT * FROM table1 inner join table2 on table1.id=table2.id since this is a bad practice. Actually I only need SELECT column1,column4,column5(most of them)...... from table1 inner join table2 on table1.id=table2.id.
So, do I have a way that replace * into all columns and then I can just COPY this text and remove some columns which I don't need and remain what I want rather than type each column name?
If you're using SQL Server, an easy trick is to open a database in Management Studio, right-click on a table and select "Select top 1000 Rows" from the context menu. You'll get all the fields listed one by one. You can copy and paste the text wherever you want.
I don't know which IDE you're using let alone which DBMS, but there's probably a trick like this one in it.
Try using the query below which is use to get all the columns of a specific table. Hope it helps you.
SELECT name FROM sys.all_columns WHERE object_id = OBJECT_ID('MyTableHere')
In MySQL, try the code below or you can refer in this Documentation:
SHOW COLUMNS FROM MyTableNameHere;
I have a query
SELECT ultrait_wpl_properties.id, location1_name, location3_name, location4_name,
field_312, field_42, post_code, lot_area, price, bedrooms, bathrooms, field_308,
googlemap_lt, googlemap_ln, street, street_no, ultrait_wpl_property_types.name,
ultrait_wpl_items.item_name
FROM ultrait_wpl_properties
JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
JOIN ultrait_wpl_items ON ultrait_wpl_properties.id = ultrait_wpl_items.id
ORDER BY ultrait_wpl_properties.id
As you can see I'm using JOINS. When it comes to inserting a new record is there a way to create an INSERT statement that will incorporate these?
What I mean is if I have the data for all the fields specified in the above query can I write an INSERT that will insert the data into the correct tables? I am currently researching this matter also but if anyone could provide any insight it would be appreciated.
No.
Or the slightly longer answer: no, the SQL standard does not provide this option.
There is a workaround: you can create a STORED PROCEDURE that accepts the input from the query and splits it into multiple INSERT statements. However: this solution will not have any of the flexibility of standard SQL statements.
Also it is not a simple matter if you have three tables joined by keys you may as well have 2 updates and one insert instead of three inserts.
So my expertise is not in MySQL so I wrote this query and it is starting to run increasingly slow as in 5 minutes or so with 100k rows in EquipmentData and 30k or so in EquipmentDataStaging (which to me is very little data):
CREATE TEMPORARY TABLE dataCompareTemp
SELECT eds.eds_id FROM equipmentdatastaging eds
INNER JOIN equipment e ON e.e_id_string = eds.eds_e_id_string
INNER JOIN equipmentdata ed ON e.e_id = ed.ed_e_id
AND eds.eds_ed_log_time=ed.ed_log_time
AND eds.eds_ed_unit_type=ed.ed_unit_type
AND eds.eds_ed_value = ed.ed_value
I am using this query to compare data rows pulled from a clients device to current data sitting within their database. From here I take the temp table and use the ID's off it to make conditional decisions. I have the e_id_string indexed and I have e_id indexed and everything else is not. I know that it looks stupid that I have to compare all this information, but the clients system is spitting out redundant data and I am using this query to find it. Any type of help on this would be greatly appreciated whether it be a different approach by SQL or MySql Management. I feel like when I do stuff like this in MSSQL it handles the requests much better, but that is probably because I have something set up incorrectly.
TIPS
index all necessary columns which are using with ON or WHERE condition
here you need to index eds_ed_log_time,eds_e_id_string, eds_ed_unit_type, eds_ed_value,ed_e_id,ed_log_time,ed_unit_type,ed_value
change syntax to SELECT STRAIGHT JOIN ... see more reference
I am trying to use the results of another query to use as a criteria for another. In my specific example, I might have four houses that are 'A', 'B', 'C', 'D' (the unique values of a field in a table called Homes).
I want to go through another query and say for each house type, what percent of residents (in Residents table) are married, which I want to do by using Count() to count the number for each Home type.
Do I need to loop through the results using VBA? Asking on a higher level, is there a way to use the results from a query as inputs into another - more than just limit the results of the new query to the results of the prior query?
Edit:
In semi-pseudo code:
For each (result of previous query) Do
New query WHERE field1 = (row of previous query)
End Do
What I am trying to ask, is there a way to accomplish this in Access using SQL? Or is this something that has to be done in VBA?
I know that if it can be done in SQL that would be the best performing and best practice, but I'm relatively inexperienced in SQL and online resources aren't always helpful because Access has it's own particular flavor of SQL.
Since you are using VBA to run this, you can loop through your recordsets and yes you can use a value from one query in the next query. There are alot of resources out there to help.
VBA: Working with RecordSets
Looping through Record Sets
Code through all records
To answer your general question, yes there is. You can do a nested query i.e. select column a from table a where column a = (select column b from table b where column b=x)
You can go as many levels deep as you want, but the caveat is the nested query can only return one column and with a specific answer set. You can also use select statements as your columns i.e
select (select column b from table b) col b from table a ..... Not the exact syntax but I would have to dig out some examples from an old project to find that.
Nested queries are useful, but for the level of precision you are looking for, a stored procedure or a view is probably a better option. Just for ease of use, I would look at creating a view of the data that you want and then querying from that to start with. More flexible than a nested query.
You need to join two tables using a common column and then get your specific column from any of the table
SELECT A.REQUIRED_FIELD from TABLEA AS A
INNER JOIN TABLEB AS B ON A.FOREIGN_KEY=B.FOREIGN_KEY
WHERE CONDITION