I'm new to MySQL. Can anyone describe lines below which I get theme from the demo of the jqgrid, what is the meaning of a.id? What is the meaning of these dots?
$SQL = "SELECT a.id, a.invdate, b.name, a.amount,a.tax,a.total,a.note FROM invheader a, clients b WHERE a.client_id=b.client_id ORDER BY $sidx $sord LIMIT $start , $limit";
You can find the example here:
http://trirand.com/blog/jqgrid/jqgrid.html
in the advanced>Multi select
You've asked several questions here. To address the dots:
In the FROM clause, a is used as an alias for the invheader table. This means you can reference that table by the short alias a instead of the full table name.
Therefore, a.id refers the the id column of the invheader table.
It is generally considered bad practice to simply give your tables the aliases a, b, c, etc. and I would recommend you use something more useful.
I suggest you read some basic MySQL tutorials as this is a fundamental principal.
The dot(.) is used to separate the board scope.So Songs.songId mean that first find the table named Songs and then in the Songs table find the field named songId.
In my opinion, that DOT NOTATION is used for fetching information from right side of the syntax. That means, a.id which means you fetch the data from "a table". In this case, you use the aliases name, then it runs '.id'which means it fetches data 'ID'from a table.If it is wrong, please comment that wrong statement. thank you
Related
I'm preparing for an exam in databases and SQL and I'm solving an exercise:
We have a database of 4 tables that represent a human resources company. The tables are:
applicant(a-id,a-name,a-city,years-of-study),
job(job-name,job-id),
qualified(a-id,job-id)
wish(a-id,job-id).
the table applicant represents the table of applicants obviously. And jobs is the table of available jobs. the table qualified shows what jobs a person is qualified for, and the table wish shows what jobs a person is interested in.
The question was to write a query that displays for each job-id, the number of applicants that are both qualified and interested to work in.
Here is the solution the teacher wrote:
Select q1.job_id
, count(q1.a_id)
from qualified as q1
, wish as w1
Where q1.a_id = w1.a_id
and q1.job_id = w1.job_id
Group by job_id;
That's all well and good, I'm not sure why we needed that "as q1" and "as w1", but i can see why it works.
And here is the solution I wrote:
SELECT job-id,COUNT(a-id) FROM job,qualified,wish WHERE (qualified.a-id=wish.a-id)
GROUP BY job-id
Why is my solution wrong? And also - From which table will it select the information? Suppose I write SELECT job-id FROM job,qualified,wish. From which table will it take the information? because job-id exists in all 3 of these tables.
You can only refer to tables mentioned in the FROM clause. If it's ambiguous (because more than one has a column of the same name) then you need to be explicit by qualifying the name. Usually the qualifier is an alias but it could also be the table name itself if an alias wasn't specified.
There's a concept of a "natural join" which joins tables on common column(s) between two tables. Not all systems support that notation but I think MySQL does. I believe these systems usually collapse the joined pairs into a single column.
select q1.job_id, count(q1.a_id) from qualified as q1, wish as w1
where q1.a_id = w1.a_id and q1.job_id = w1.job_id
group by job_id;
I don't think I've worked on any systems that would have accepted the query above because the grouping column would have been strictly unclear even though the intention really is not. So if it truly does work correctly on MySQL then my guess is that it recognizes the equivalence of the columns and cuts you some slack on the syntax.
By the way, your query appears to be incorrect because you only included a single column in a join that requires two columns. You also included a third table which means that your result will effectively do a cross join of every row in that table. The grouping is going to still going to reduce it to one row per job_id but the count is going to be multiplied by the number of rows in the job table. Perhaps you added that table thinking it would hurt to add it just in case you need it but that is not what it means at all.
Your query will list non-existing jobs in case the database has orphan records in applicant and qualified, and might also omit jobs that have no qualified and willing candidates.
I'm not exactly sure, because I have no idea if there's any database that will accept COUNT(a-id) when there's no information about the table from which to take this value.
edit: Interestingly it looks like both of these problems are shared by both of the solutions, but shawnt00 has a point: your solution makes a huge pointless cartesian of three tables: see it without the group by.
My current best guess for a working answer would therefore be http://sqlfiddle.com/#!9/09d0c/6
I have a table used for lookups which stores the human-readable value in one column and a the same text stripped of special characters and spaces in another. e.g., the value "Children's Shows" would appear in the lookup column as "childrens-shows".
Unfortunately the corresponding main table isn't quite that simple - for historical reasons I didn't create myself and now would be difficult to undo, the lookup value is actually stored with surrounding asterisks, e.g. '*childrens-shows*'.
So, while trying to join the lookup table sans-asterisks with the main table that has asterisks, I figured CONCAT would help me add them on-the-fly, e.g.;
SELECT *
FROM main_table m
INNER JOIN lookup_table l
ON l.value = CONCAT('*',m.value,'*')
... and then the table was toast. Not sure if I created an infinite loop or really screwed the data, but it required an ISP backup to get the table responding again. I suspect it's because the '*' symbol is probably reserved, like a wildcard, and I've asked the database to do the equivalent of licking its own elbow. Either way, I'm hesitant to 'experiment' to find the answer given the spectacular way it managed to kill the database.
Thanks in advance to anyone who can (a) tell me what the above actually did to the database, and (b) how I should actually join the tables?
When using CONCAT, mysql won't use the index. Use EXPLAIN to check this, but a recent problem I had was that on a large table, the indexed column was there, but the key was not used. This should not bork the whole table however, just make it slow. Possibly it ran out of memory, started to swap and then crashed halfway, but you'd need to check the logs to find out.
However, the root cause is clearly bad table design and that's where the solution lies. Any answer you get that allows you to work around this can only be temporary at best.
Best solution is to move this data into a separate table. 'Childrens shows' sounds like a category and therefore repeated data in many rows. This should really be an id for a 'categories' table, which would prevent the DB from having to run CONCAT on every single row in the table, as you could do this:
SELECT *
FROM main_table m
INNER JOIN lookup_table l
ON l.value = m.value
/* and optionally */
INNER JOIN categories cat
ON l.value = cat.id
WHERE cat.name = 'whatever'
I know this is not something you may be able to do given the information you supplied in your question, but really the reason for not being able to make such a change to a badly normalised DB is more important than the code here. Without either the resources or political backing to do things the right way, you will end up with even more headaches like this, which will end up costing more in the long term. Time for a word with the boss perhaps :)
I noticed te other day I can joins in mysql just as easily by doing,
SELECT peeps, persons, friends FROM tablea JOIN tableb USING (id) WHERE id = ?
In stead of using,
SELECT a.peeps, a.persons, b.friends FROM tablea a JOIN tableb b USING (id) WHERE id = ?
It only works if there is no matching column names, why should I do the second rather than the first?
No, you don't need to, but in my humble opinion you really should. It's almost always better in my experience to be explicit with what you're trying to do.
Consider the feelings of the poor guy (or girl) who has to come behind you and try to figure out what you were trying to accomplish and in which tables each column resides. Explicitly stating the source of the column allows one to look at the query and glean that information without deep knowledge of the schema.
Query 1 will work (as long as there are no ambiguous column names).
Query 2 will
be clearer
be more maintainable (think of someone who doesn't know the database schema by heart)
survive the addition of an ambiguous column name to one of the tables
So, don't be lazy because of that pitiful few saved keystrokes.
It's not necessary if you have no duplicate column names. If you do, the query will fail.
I'm working on a MySQL database for a social network site I'm building, and so far it's been a great learning experience. However, there has been one thing in particular that's always confused me.
When seeking answers to a particular issue, I see so many examples that use dots in their naming conventions in their MySQL queries. For example:
SELECT c.id, c.comment, c.user_id, u.username, u.photo
FROM (comments c)
JOIN users u ON c.user_id = u.id
WHERE c.topic_id = 9
and here is another example:
SELECT fb.auto_id, fb.user_id, fb.bulletin, fb.subject, fb.color, fb.submit_date, fru.disp_name, fru.pic_url
FROM friend_bulletin AS fb
LEFT JOIN friend_friend AS ff ON fb.user_id = ff.userid
LEFT JOIN friend_reg_user AS fru ON fb.user_id = fru.auto_id
WHERE (
ff.friendid =1
AND ff.status =1
)
LIMIT 0 , 30
Is there a particular benefit to using the dots in the names? As someone who comes from doing a lot of CSS work, at first glance the dots appear to me as some kind of association between different things, but what are they for here?
I suppose I just want to make sure I'm not making my database structure/queries less efficient by not using this 'dot' naming convention. If someone could explain to me in laymen's terms what they are used for, I'd really appreciate it.
stuff.whatever should be thought of as table_name.column_name. You're explicitly associating each column reference with the table it belongs to which, IMHO, is a best practice to follow.
You shouldn't think of the dots as being part of a "naming convention." The functionality is more similar to calling an attribute on an object.
In the case of stuff.whatever 'stuff'
represents the database table and
whatever represents the data in a column called 'whatever' in the database.
If you've seen a column referenced without the table portion, it is because the user is expecting mysql to figure out which column they mean.
If there is only one table in the query with a column of that name, mysql can do it, no problem.
But, for example, you have a "facebook" table and a "twitter" table and you join them through a query because they both have a "user_id" column or something, and they BOTH have an "avatar_image" column and you didn't specify the table, mysql would raise en error telling you it didn't know exactly what you were asking for.
There is nothing wrong with using full name conventions, however, if you have long table, field names, it is easier to use alias for readability purpose.
Nicklas, thanks for the answer to my previous question....
Forgive me for my ignorance and for asking what may turn out to be rather simple questions, but databases are not my area of expertise.
The select statement that gives me the number of crashes in each percinct:
SELECT P.precinct, count(C) FROM nycpp P, nyccrash C WHERE _st_contains(P.the_geom, C.crashpoint) GROUP BY P.precinct ORDER BY P.precinct;
I want to add just the count to my nycpp table the variable that will hold the count is number_of crashes....
Thanks again the assistance
Chris
Hallo
I assume that precinct is the unique id in nycpp, then you can try:
update nycpp set number_of crashes=a.n_crashes from
(SELECT P.precinct, count(C) as n_crashes FROM nycpp P, nyccrash C
WHERE _st_contains(P.the_geom, C.crashpoint)
GROUP BY P.precinct
ORDER BY P.precinct) a
where nycpp.precinct=a.precinct;
But why do you use _st_contains instead of st_contains
the underscore version will not use your spatial indexes, but st_contains will do a first indexscan finding intersecting bouning boxes before running theunderscore version.
So, you probably absolutely want to use st_contains instead of contains. If your tables are big enough for needing index: In this query the spatial indexes is important on both tables and an index on precinct. Don't forget to analyse the table after creating the indexes to make them work.
BTW, I think you are supposed to mark the questions as answered if you are satisfied with the answer so others don't have to try to answer them.
HTH
Nicklas