This is actually a two part question.
First: I was wondering if there is a way to display the information in a view I just created. I couldn't find anything online that was similar to the DISPLAY Tables query that could be used for views.
The query to create my view is:
CREATE VIEW View1 AS
SELECT *
FROM CustOrder
WHERE shipToName = 'Jim Bob'
Secondly, once I find out how to display that specific view from above, how do I go about finding the highest "paidPrice" (a column in the CustOrder table)?
Thank you all in advance!
In answer to Question 1:
SHOW CREATE VIEW view_name;
reference:
http://dev.mysql.com/doc/refman/5.7/en/show-create-view.html
A view is little more than a stored SELECT statement, but from the perspective of the client, they are mostly equivalent to real tables. To interact with a view you have created, you may simply issue SELECT statements against it.
-- Regular SELECT statements, no different
-- from querying against a real table.
-- Get all rows from the view
SELECT * FROM View1
-- Get the MAX() value from a column
SELECT MAX(paidPrice) AS maxprice FROM View1
You may also create views which represent multiple joined tables. This is a common use case, wherein many tables are frequently joined for querying. You may use a view to handle the joins, and expose only certain columns to certain database users rather than grant full access to your schema.
CREATE VIEW joinview AS (
SELECT
t1.id,
t1.col1,
t1.col2,
-- The view will only expose the alias
t1.col3 AS aliased_name,
-- Use an alias to avoid a column name collision
t2.col1 AS t2c1,
-- The view will expose the column name without the table name
t2.col99
FROM
t1 INNER JOIN t2 ON t1.id = t2.t1_id
);
Now the view will only expose columns as a SELECT query would. You will no longer need to reference the individual tables, since it produces a flat output.
-- Retrieve 2 columns from the join view
SELECT col99, aliased_name FROM joinview
Finally, because views act just like normal tables, you can join them to other tables or views too. Take care when assembling views with joins though, to be sure that the underlying tables are appropriately indexed. Otherwise, the views may perform poorly (just as they would for normal SELECT queries executed without appropriate indexing).
Related
My scenario is as follows( in MySQL)
I have a table say table 1, which has 2 columns:
userID, column_acess
Table 2 which has a list of columns say col1,col2,col3, etc.
Now What I would like to do is use pymySQL to query table 1 for the columns a particular userID is allowed to acesss, by inspecting the column, acess field ( which will contain a comma seperated list of columns in tabl2), and use that result in another sql query ( which works on table2) to actually get the data from the respective columns a user is allowed to acess.
So essentially I would like something like:
Select (Select column_acess from tabl1 where user_ID='123') from table2
So inner query should return the list of columns say col1, col2, which would be used to select the columns in the outer query in table2
How do I do that in mySQL?
I strongly encourage you too read this post. You should either first store columns in variable or use dynamic sql query. Use SELECT result as COLUMN name in other SELECT
BTW your schema is not even in 1 NF since you don’t have atomic values in table 1. You should avoid that.
MySQL supports the granting of column-level privileges to users, using the standard grant statement.
I would suggest that you start with the documentation on this subject.
An alternative to using grant for columns is to create views for different user types. This is, in fact, the more general solution, because the views can filter rows as well as columns. The idea is that the underlying tables are not directly accessible. The views are, so all access needs to go through the views.
I have a dozen of tables with the same structure. All of their names match question_20%. Each table has an indexed column named loaded which can have values of 0 and 1.
I want to count all of the records where loaded = 1. If I had only one table, I would run select count(*) from question_2015 where loaded = 1.
Is there a query I can run that finds the tables in INFORMATION_SCHEMA.TABLES, sums over all of these counts, and produces a single output?
You can do what you want with dynamic SQL.
However, you have a problem with your data structure. Having multiple parallel tables is usually a very bad idea. SQL supports very large tables, so having all the information in one table is a great convenience, from the perspective of querying (as you are now learning) and maintainability.
SQL offers indexes and partitioning schemes for addressing performance issues on large tables.
Sometimes, separate tables are necessary, to meet particular system requirements. If so, then a view should be available to combine all the tables:
create view v_tables as
select t1.*, 'table1' as which from table1 union all
select t2.*, 'table2' as which from table2 union all
. . .
If you had such a view, then your query would simply be:
select which, count(*)
from v_tables
where loaded = 1
group by which;
I have a query like this :
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo WHERE group='BEST'
Basically, the table name for the main query is fetched through the subquery.
I get an error that #1054 - Unknown column 'group' in 'where clause'
When I investigate (removing the where clause), I find that the query only returns the subquery result at all times.
Subquery table adm_linkedfields has structure id | name | linktable
Currently am using MySQL with PDO but the query should be compatible with major DBs (viz. Oracle, MSSQL, PgSQL and MySQL)
Update:
The subquery should return the name of the table for the main query. In this case it will return tbl_company
The table tbl_company for the main query has this structure :
id | name | group
Thanks in advance.
Dynamic SQL doesn't work like that, what you created is an inline-view, read up on that. What's more, you can't create a dynamic sql query that will work on every db. If you have a limited number of linktables you could try using left-joins or unions to select from all tables but if you don't have a good reason you don't want that.
Just select the tablename in one query and then make another one to access the right table (by creating the query string in php).
Here is an issue:
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo
WHERE group='BEST';
You are selecting from DT which contains only one column "linktable", then you cant put any other column in where clause of outer block. Think in terms of blocks the outer select is refering a DT which contains only one column.
Your problem is similar when you try to do:
create table t1(x1 int);
select * from t1 where z1 = 7; //error
Your query is:
SELECT *
FROM (SELECT linktable
FROM adm_linkedfields
WHERE name = 'company'
) cbo
WHERE group='BEST'
First, if you are interested in cross-database compatibility, do not name columns or tables after SQL reserved words. group is a really, really bad name for a column.
Second, the from clause is returning a table containing a list of names (of tables, but that is irrelevant). There is no column called group, so that is the problem you are having.
What can you do to fix this? A naive solution would be to run the subquery, run it, and use the resulting table name in a dynamic statement to execute the query you want.
The fundamental problem is your data structure. Having multiple tables with the same structure is generally a sign of a bad design. You basically have two choices.
One. If you have control over the database structure, put all the data in a single table, linktable for instance. This would have the information for all companies, and a column for group (or whatever you rename it). This solution is compatible across all databases. If you have lots and lots of data in the tables (think tens of millions of rows), then you might think about partitioning the data for performance reasons.
Two. If you don't have control over the data, create a view that concatenates all the tables together. Something like:
create view vw_linktable as
select 'table1' as which, t.* from table1 t union all
select 'table2', t.* from table2 t
This is also compatible across all databases.
I have the following question. I have two tables and I want to store them separately. However, in my application I need to regularly perform UNION operation on them, so I effectively need to treat them as one. I think this is not good in terms of performance. I was thinking about creating the following view:
CREATE VIEW merged_tables(fields from both tables) AS
SELECT * FROM table_a
UNION
SELECT * FROM table_b
How does it impact on the performance of SELECT query? Does it have any real impact (inner representation is different) or it is just a matter of using a simpler query to select?
Using a UNION inside a view will be no different in performance than using the UNION in a discrete SELECT statement. Since you are using SELECT * on both tables and require no inner complexity (e.g. no JOINS or WHERE clauses), there won't really be any way to further optimize it.
However, if the tables do hold similar data and you want to keep them logically separated, you might consider storing it all in one table with a boolean column that indicates whether a row would otherwise have been a resident of table_a or table_b. You gain a way to tell the rows apart and avoid the added confusion of the UNION then, and performance isn't significantly impacted either.
It is just a matter of using a simpler query to select. There will be no speed difference, however the cost of querying the union should not be much worse (in most cases) than if you kept all the data in a single table.
If the tables are really the same structure, you could also consider another design in which you used a single table for storage and two views to logically separate the records:
CREATE VIEW table_a AS SELECT * FROM table_all WHERE rec_type = 'A'
CREATE VIEW table_b AS SELECT * FROM table_all WHERE rec_type = 'B'
Because these are single-table, non-aggregated VIEWs you can use them like tables in INSERT, UPDATE, DELETE, and SELECT but you have the advantage of also being able to program against table_all when it makes sense. The advantage here over your solution is that you can update against either the table_a, table_b entities or the table_all entity, and you don't have two physical tables to maintain.
What are views in MySQL? What's the point of views and how often are they used in the real world?
Normal Views are nothing more then queryable queries.
Example:
You have two tables, orders and customers, orders has the fields id, customer_id, performance_date and customers has id, first_name, last_name.
Now lets say you want to show the order id, performance date and customer name together instead of issuing this query:
SELECT o.id as order_id, c.first_name + ' ' + c.last_name as customer_name,
o.performance_date
FROM orders o inner join customers c
you could create that query as a view and name it orders_with_customers, in your application you can now issue the query
SELECT *
FROM orders_with_customer
One benefit is abstraction, you could alter the way you store the customers name, like inlcuding a middle name, and just change the views query. All applications that used the view continue to do so but include the middle name now.
It's simple: views are virtual tables.
Views are based on SELECT-queries on "real" tables, but the difference is that views do not store the information unlike real tables. A view only references to the tables and combines them the way SELECT says them to. This makes often used queries a lot more simplified.
Here's a simple example for you. Lets suppose you have a table of employees and a table of departments, and you'd like to see their salaries. First you can create a view for the salaries.
CREATE VIEW SALARIES
AS
SELECT e.name,
e.salary,
d.name
FROM employees AS e, deparments as d
WHERE e.depid = d.depid
ORDER BY e.salary DESC
This query lists the name of the employee, his/her salary and department and orders them by their salaries in descending order. When you've done this you can use queries such as:
SELECT * from SALARIES
On a larger scale you could make a view that calculates the average salary of the employees and lists who has a salary that's less than the average salary. In real life such queries are much more complex.
In mysql a view is a stored select statement
Look to this answer: MySQL Views - When to use & when not to
You can think of the view as a on-the-fly generated table. In your queries it behaves like an ordinary table but instead of being stored on the disk, it is created on the fly when it is necessary from a SQL statement that is defined when creating a view.
To create a view, use:
CREATE VIEW first_names AS SELECT first_name FROM people WHERE surname='Smith'
You can then use this view just as an ordinary table. The trick is when you update the table people the first_names view will be updated as well because it is just a result from the SELECT statement.
This query:
SELECT * FROM first_names
will return all the first names of people named Smith in the table people. If you update the people table and re-run the query, you will see the updated results.
Basically, you could replace views with nested SELECT statements. However, views have some advantages:
Shorter queries - nested SELECT statements make the query longer
Improved readability - if the view has a sensible name, the query is much easier to understand
Better speed - the view's SELECT statement is stored in the database engine and is pre-parsed, therefore it doesn't need to be transferred from the client and parsed over and over again
Caching and optimizations - the database engine can cache the view and perform other optimizations
They're a shorthand for common filters.
Say you have a table of records with a deleted column. Normally you wouldn't be interested in deleted records and hence you could make a view called Records that filters out deleted records from the AllRecords table.
This will make your code cleaning since you don't have to append/prepend deleted != 1 to every statement.
SELECT * FROM Records
would return all not-deleted records.
In simple words
In SQL, a view is a virtual table
based on the result-set of an SQL
statement.
A view contains rows and columns, just
like a real table. The fields in a
view are fields from one or more real
tables in the database.
You can add SQL functions, WHERE, and
JOIN statements to a view and present
the data as if the data were coming
from one single table.
Source
In addtion to this, you can insert rows in an underlying table from a view provided that the only one table is referred by the view and columns which are not referred in the view allow nulls.
A view is a way of pre-defining certain queries. It can be queried just like a table, is defined by a query rather than a set of on-disk data. Querying it allows you to query the table's results.
In most cases, querying a view can be seen as equivalent to using the view's defining query as a subquery in your main query. Views allow queries to be shorter and more modular (as the common parts are defined separately in the view). They also provide opportunity for optimization (although not all databases do so; I am not sure if MySQL provides any optimizations to make views faster or not).
If you update the underlying tables, queries against the view will automatically reflect those changes.