Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Agrikk
Oct 17, 2003

Take care with that! We have not fully ascertained its function, and the ticking is accelerating.
This is a rediculously retarded question and I should be able to do this by now, but I can't get my head around it:


Given a data field [YearMonth] [int] with format yyyymm

How do I get the last day of that month with a format of yyyy-mm-dd?

Edit: in MS-SQL. Sorry.

Agrikk fucked around with this message at 20:50 on Apr 2, 2012

Adbot
ADBOT LOVES YOU

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine
In MySQL at least, SELECT LAST_DAY(STR_TO_DATE(datecolumn, "%Y%m")).

JeansW
Aug 4, 2004
Yes. Like the jeans...

Agrikk posted:

This is a rediculously retarded question and I should be able to do this by now, but I can't get my head around it:


Given a data field [YearMonth] [int] with format yyyymm

How do I get the last day of that month with a format of yyyy-mm-dd?

Edit: in MS-SQL. Sorry.

You can just convert the Year Month to a date time (with a day of 1) and then add a month to it (to get the 1st day of the next month) and then minus a day.

So it'd be:
code:
SELECT DATEADD(D, -1, DATEADD(M, 1, CONVERT(DATETIME, CAST(YearMonth AS VARCHAR(8)) + '01', 112)))

JeansW fucked around with this message at 21:23 on Apr 2, 2012

Agrikk
Oct 17, 2003

Take care with that! We have not fully ascertained its function, and the ticking is accelerating.

JeansW posted:

You can just convert the Year Month to a date time (with a day of 1) and then add a month to it (to get the 1st day of the next month) and then minus a day.

So it'd be:
code:
SELECT DATEADD(D, -1, DATEADD(M, 1, CONVERT(DATETIME, CAST(YearMonth AS VARCHAR(8)) + '01', 112)))

Oh. Of course. Duh.


Thanks!

Steakandchips
Apr 30, 2009

I need to learn SQL on my own time, for a new job I'm about to start within the firm I already work in.

Background:
- Massive multinational firm.
- Database that I will be working with currently has over 16 million records.
- Each record has approximately 200 fields available in it (for the average record though, only 10-50 of those fields are populated though).
- I use this database as an enduser currently, i.e. inputting data, querying data using the enduser GUI, amending data etc. I know the database's structure pretty well, i.e. in which table things belong etc, e.g. the field/attribute Country belongs in table/concept Product.

I'll be required to do things like run queries similar to:

Pull out all records that have ExpiryDate<TODAY, Type=Common, Country=FR
Pull out all records that have Status=Active, TaxType≠NULL

I am currently on leave. I'd like to basically understand the syntax of SQL and the basic manner in how and where to enter such queries.

Can someone recommend me a decent beginners guide online?

DankTamagachi
Jan 20, 2005
Tamagachi to your throat!

Steakandchips posted:

I need to learn SQL on my own time, for a new job I'm about to start within the firm I already work in.

Background:
- Massive multinational firm.
- Database that I will be working with currently has over 16 million records.
- Each record has approximately 200 fields available in it (for the average record though, only 10-50 of those fields are populated though).
- I use this database as an enduser currently, i.e. inputting data, querying data using the enduser GUI, amending data etc. I know the database's structure pretty well, i.e. in which table things belong etc, e.g. the field/attribute Country belongs in table/concept Product.

I'll be required to do things like run queries similar to:

Pull out all records that have ExpiryDate<TODAY, Type=Common, Country=FR
Pull out all records that have Status=Active, TaxType≠NULL

I am currently on leave. I'd like to basically understand the syntax of SQL and the basic manner in how and where to enter such queries.

Can someone recommend me a decent beginners guide online?

Personally, I really like Tizag's tutorials:
http://www.tizag.com/sqlTutorial/

They're a great starting point and should definitely get you through the basics. After that, stackoverflow is a great resource for weird one-off questions.

mindphlux
Jan 8, 2004

by R. Guyovich
Alright, I thought I was done with the Access related questions (is there a better place to ask them in SH/SC?), but I have one I can't figure out.

I have a form that acts as a front-end search tool for a SQL database. This form is a 'split form' - the top is a form with a couple of comboboxes I programmed up to search fields, and the bottom is a datasheet.

When you enter more than 4 characters in the combobox, some VB code runs a SQL query to populate its dropdown, then you select your record from the dropbox, and then a query runs to populate the datasheet with the relevant records. then I setfocus back to the combobox. all works fine.

I've run into a problem though. A user wants to export the contents of the datasheet to excel, and she's just doing the standard 'external data->export to excel' steps. What's exporting, though, is the recordset for my combobox, rather than what's in the datasheet. Can't figure out how to export the datasheet.

only thing that works is if I switch from split form view to datasheet view, but of course this isn't ideal from an ease of use standpoint.

Any thoughts?

Steakandchips
Apr 30, 2009

DankTamagachi posted:

Personally, I really like Tizag's tutorials:
http://www.tizag.com/sqlTutorial/

They're a great starting point and should definitely get you through the basics. After that, stackoverflow is a great resource for weird one-off questions.

You sir, are a scholar and a gentleman.

Teh z0rceror
Dec 14, 2004

Any oracle guys in here?

I'm trying to figure out if a user can create tables to a non default tablespace. I'm testing this install and they added a "feature" to install tables to a non default tablespace.

Its more than likely the code is broke, but I started thinking about it and i've never used anything other than the default tablespace.

Goat Bastard
Oct 20, 2004

Teh z0rceror posted:

Any oracle guys in here?

I'm trying to figure out if a user can create tables to a non default tablespace. I'm testing this install and they added a "feature" to install tables to a non default tablespace.

Its more than likely the code is broke, but I started thinking about it and i've never used anything other than the default tablespace.

Yea you can. Check out the generated DDL for one of your tables in a tool like SQL Developer - there's heaps of storage options that you can specify if you want, but never really need to.

code:
CREATE TABLE "SANDBOX"."TEST"
  (
    "ID" NUMBER
  )
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE
  (
    INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT
  )
  TABLESPACE "USERS" ;

G-Dub
Dec 28, 2004

The Gonz

mindphlux posted:

Any thoughts?

I can't say for sure without seeing the app but is it maybe because the combobox has focus? I have never used that feature of Access so I can't say for sure.

To ensure it does what you want it to do you could look in to the Excel object model and create your own export to Excel function, and add a button to your form. It's really quite easy. My one clue is 'CopyFromRecordset'. I have seen too many people iterate through recordsets (takes forever) instead of using this function which takes a tiny fraction of a second.

mindphlux
Jan 8, 2004

by R. Guyovich

G-Dub posted:

I can't say for sure without seeing the app but is it maybe because the combobox has focus? I have never used that feature of Access so I can't say for sure.

To ensure it does what you want it to do you could look in to the Excel object model and create your own export to Excel function, and add a button to your form. It's really quite easy. My one clue is 'CopyFromRecordset'. I have seen too many people iterate through recordsets (takes forever) instead of using this function which takes a tiny fraction of a second.

yeah, that was my thought too. I hadn't come across copyfromrecordset, thanks for the tip. I'll probably end up adding a button if the client can't deal with switching to datasheet view.

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
I'm writing something that needs to save to and pull from dictionary information in a database.

E.g. I'll be adding this: http://en.wiktionary.org/wiki/deus#Inflection

into a table along with a bunch of other words that decline along a similar vein. Normally there'll only be one value per field, i.e "Nominative Singular" would just be "deus" and nominative plural would just be "dei" on the vast majority of words I'm looking at. Except I do need to be able to handle multiple words per field for irregular words such as this one.

My question is, how should I handle it from a DB perspective? Have the field be long enough to contain 'dei.di.dii' and attempt to explode (un-delimit) every field I query? Or create an extra field with a status that denotes that one of the entries in that row has multiple acceptable forms? Or create an extra field for every entry saying the same? Or should the field identify which entries have extra forms by way of: 111112323133 (e.g. how many forms per field, 1 being standard, and just count like that), or some other more mathematically-efficient identifier?

Or should I skip the delimited thing entirely and just create a custom table for irregular forms and manually add 3 fields per declension, meaning that every noun will have 36 fields, with a minimum of 12 used (and the remaining 24 normally empty), and grab them all every time I query that irregular noun?

Obviously the database would be more efficient if I just crammed more info into the field and delimited it, to be processed by the script. Should I then just add an extra field for every row (regardless of regularity) and just state using a hex value (or something) how many values there are in each field?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Sulla-Marius 88 posted:

I'm writing something that needs to save to and pull from dictionary information in a database.

E.g. I'll be adding this: http://en.wiktionary.org/wiki/deus#Inflection

into a table along with a bunch of other words that decline along a similar vein. Normally there'll only be one value per field, i.e "Nominative Singular" would just be "deus" and nominative plural would just be "dei" on the vast majority of words I'm looking at. Except I do need to be able to handle multiple words per field for irregular words such as this one.

My question is, how should I handle it from a DB perspective? Have the field be long enough to contain 'dei.di.dii' and attempt to explode (un-delimit) every field I query? Or create an extra field with a status that denotes that one of the entries in that row has multiple acceptable forms? Or create an extra field for every entry saying the same? Or should the field identify which entries have extra forms by way of: 111112323133 (e.g. how many forms per field, 1 being standard, and just count like that), or some other more mathematically-efficient identifier?

Or should I skip the delimited thing entirely and just create a custom table for irregular forms and manually add 3 fields per declension, meaning that every noun will have 36 fields, with a minimum of 12 used (and the remaining 24 normally empty), and grab them all every time I query that irregular noun?

Obviously the database would be more efficient if I just crammed more info into the field and delimited it, to be processed by the script. Should I then just add an extra field for every row (regardless of regularity) and just state using a hex value (or something) how many values there are in each field?

I don't understand enough about Latin to be able to completely understand the problem domain, but I will attempt to give you a couple of pointers:

Storing comma-delimited arrays (as in your "store 'dei.di.dii' in one column" idea) is not generally a good idea. It makes it enormously complicated to extract subsets of that information or filter by it in a query. For example, if you wanted to know how many words have both a form that ends in "i" and another form that ends in "ii" you would have to write a really complicated query to try to work it out. A case can be made for doing it, but only if you are sure you'll never want to do anything other than retrieving the data in the column in the same form you put it in (i.e. you won't want to retrieve only parts of it, and you won't want to involve the contents of the column in SQL logic, such as a WHERE clause).

If there are multiple possible versions for each word (or for each word in each possible grammatical situation) then you may be best served by having two tables, Word and WordVersion. Here WordVersion has a foreign key back to Word. If a word has only one version then there's just one corresponding row in each table. If a word has n versions then there's one row in Word but n rows in WordVersion. I am guessing that this would work better than special-casing irregular words by giving them their own table, but I can't guarantee this. Like I said, I don't know much about Latin.

FamDav
Mar 29, 2008
I have a question that I haven't been able to find the answer to, though I'm pretty sure I'm just not phrasing it correctly for it to come up on google.

What is the best way to create a table schema where I will have a variable number of column entries? Should I just put a maximum bound on it and have unfilled entries default to NULL?

To be specific, I want to have recipes that are searchable by ingredient. The list of ingredients can vary in size, though a reasonable bound would be 15 or 20 ingredients. My best approach is to have a recipe table with columns for ingredients_id0-19 and a corresponding ingredients table.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

FamDav posted:

I have a question that I haven't been able to find the answer to, though I'm pretty sure I'm just not phrasing it correctly for it to come up on google.

What is the best way to create a table schema where I will have a variable number of column entries? Should I just put a maximum bound on it and have unfilled entries default to NULL?

To be specific, I want to have recipes that are searchable by ingredient. The list of ingredients can vary in size, though a reasonable bound would be 15 or 20 ingredients. My best approach is to have a recipe table with columns for ingredients_id0-19 and a corresponding ingredients table.

You need a table RecipeIngredient which contains the ingredients for recipes - one row per ingredient. Each row of the table will specify one ingredient, as well as indicating the recipe to which it corresponds (a foreign key).

Having a hard-coded set of columns is a design error. It will make it hard work to search for, say, recipes using a specific ingredient. (Imagine writing a query with a WHERE clause that says Ingredient0 = 'tomato' OR ingredient2 = 'tomato' OR ingredient3 = 'tomato' OR ...) And if you increased the number of columns you'd have to rewrite all your queries.

In comparison, if you set up a RecipeIngredient table as I suggest, you can join Recipe to RecipeIngredient and search in the RecipeIngredient table for a specific ingredient. Much simpler and there is no artificial restriction on number of ingredients.

You might want to have an Ingredient table and have RecipeIngredient serve as a cross-reference table that has foreign keys to both tables. (Then your RecipeIngredient table would have maybe 3 columns: Recipe, Ingredient, and Quantity.)

FamDav
Mar 29, 2008

Hammerite posted:

You need a table RecipeIngredient which contains the ingredients for recipes - one row per ingredient. Each row of the table will specify one ingredient, as well as indicating the recipe to which it corresponds (a foreign key).

Having a hard-coded set of columns is a design error. It will make it hard work to search for, say, recipes using a specific ingredient. (Imagine writing a query with a WHERE clause that says Ingredient0 = 'tomato' OR ingredient2 = 'tomato' OR ingredient3 = 'tomato' OR ...) And if you increased the number of columns you'd have to rewrite all your queries.

In comparison, if you set up a RecipeIngredient table as I suggest, you can join Recipe to RecipeIngredient and search in the RecipeIngredient table for a specific ingredient. Much simpler and there is no artificial restriction on number of ingredients.

You might want to have an Ingredient table and have RecipeIngredient serve as a cross-reference table that has foreign keys to both tables. (Then your RecipeIngredient table would have maybe 3 columns: Recipe, Ingredient, and Quantity.)

Ohhh, that makes so much more sense. Thanks.

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights
Movies table: MovieID, Movie
Actors table: ActorID, Actor
Relationship table: RelationshipID, ActorID, MovieID

So I have a database with these three tables. Is there a Join query I can write that will return a movie and all of the actors in the movie in a single row? For example:

Bruce Willis - The Six Sense - Die Hard - Mercury Rising

I'm really new to SQL and am having trouble grasping whether this is something that's possible. So far my results have been looking like

Bruce WIllis - The Sixth Sense
Bruce Willis - Die Hard
Bruce Willis - Mercury Rising

Thanks in advance, sorry for such an elementary question.

E: God damnit let me fix the formatting on that.

Good Will Punting fucked around with this message at 20:15 on Apr 7, 2012

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Good Will Punting posted:

Movies table: MovieID, Movie
Actors table: ActorID, Actor
Relationship table: RelationshipID, ActorID, MovieID

So I have a database with these three tables. Is there a Join query I can write that will return a movie and all of the actors in the movie in a single row? For example:

Bruce Willis - The Six Sense - Die Hard - Mercury Rising

I'm really new to SQL and am having trouble grasping whether this is something that's possible. So far my results have been looking like

Bruce WIllis - The Sixth Sense
Bruce Willis - Die Hard
Bruce Willis - Mercury Rising

Thanks in advance, sorry for such an elementary question.

E: God damnit let me fix the formatting on that.

If you are using MySQL you can use the GROUP_CONCAT function. This is not part of standard SQL and doesn't necessarily have equivalents in other RDBMSs, so if you are using another RDBMS it may be more complicated. Maybe in other RDBMS it can be expressed as a trivial case of using pivot tables?

nb. The movie names will all be in one column, not each in their own column.

Something like the following

code:
SELECT
    Actor,
    GROUP_CONCAT(Movie)
FROM
    Relationship
    JOIN Actor ON Relationship.ActorID = Actor.ActorID
    JOIN Movie ON Relationship.MovieID = Movie.MovieID
GROUP BY
    ActorID

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights
Thanks for the answer. GROUP_CONCAT is exactly what I'm looking for. Unfortunately, I'm doing this in SQL Server (school project) so I'm looking at work-arounds now. GROUP_CONCAT is really cool though, and I had never heard of it before your reply, so thanks for that!

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING

Hammerite posted:

...

If there are multiple possible versions for each word (or for each word in each possible grammatical situation) then you may be best served by having two tables, Word and WordVersion. Here WordVersion has a foreign key back to Word. If a word has only one version then there's just one corresponding row in each table. If a word has n versions then there's one row in Word but n rows in WordVersion. I am guessing that this would work better than special-casing irregular words by giving them their own table, but I can't guarantee this. Like I said, I don't know much about Latin.

You're right about the querying -- I'd like to be able to do statistical analyses on the dictionary and its contents once its filled up a bit.

However I'm not entirely sure about the format you're suggesting here, are you saying that there is a 1:1 duplication of the contents of Word and WordVersion, except that WordVersion has the potential for supplementary rows with extra info? Forget the Latin, I'll give an example that'll stand on its own:

code:
Table: Word:

         Basket1  Basket2  Basket3  Basket4  Basket5  Basket6
Jeff     apple     pear     banana   orange  apple    grapes
Simon    apple     banana   orange   orange  banana   pear

and Table: WordVersion:

         Basket1  Basket2  Basket3  Basket4  Basket5  Basket6
Jeff     apple     pear     banana   orange  apple    grapes
Jeff               mango                     banana   apple
Jeff               apple
Simon    apple     banana   orange   orange  banana   pear
I.e. they're duplicated 1:1 from 'Word', but 'WordVersion' has the potential for additional rows for specific items, if supplementary info exists?

I'm seeing a few problems/oddities with that idea so I'm sure I'm misunderstanding you..

My issue is then, with splitting the info into multiple rows/tables, wouldn't it make the database quite inefficient, that the script has to do a SELECT * WHERE query through multiple tables and multiple rows every time I query anything, just to make sure I'm getting all the info, when 90% of the time there won't be multiple rows? Or should I add to the original row in 'Word' a binary flag saying 'Multiple', which the script gets and then if it's true, does a further search for supplementary values?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Sulla-Marius 88 posted:

You're right about the querying -- I'd like to be able to do statistical analyses on the dictionary and its contents once its filled up a bit.

However I'm not entirely sure about the format you're suggesting here, are you saying that there is a 1:1 duplication of the contents of Word and WordVersion, except that WordVersion has the potential for supplementary rows with extra info? Forget the Latin, I'll give an example that'll stand on its own:

code:
Table: Word:

         Basket1  Basket2  Basket3  Basket4  Basket5  Basket6
Jeff     apple     pear     banana   orange  apple    grapes
Simon    apple     banana   orange   orange  banana   pear

and Table: WordVersion:

         Basket1  Basket2  Basket3  Basket4  Basket5  Basket6
Jeff     apple     pear     banana   orange  apple    grapes
Jeff               mango                     banana   apple
Jeff               apple
Simon    apple     banana   orange   orange  banana   pear
I.e. they're duplicated 1:1 from 'Word', but 'WordVersion' has the potential for additional rows for specific items, if supplementary info exists?

I'm seeing a few problems/oddities with that idea so I'm sure I'm misunderstanding you..

My issue is then, with splitting the info into multiple rows/tables, wouldn't it make the database quite inefficient, that the script has to do a SELECT * WHERE query through multiple tables and multiple rows every time I query anything, just to make sure I'm getting all the info, when 90% of the time there won't be multiple rows? Or should I add to the original row in 'Word' a binary flag saying 'Multiple', which the script gets and then if it's true, does a further search for supplementary values?

I'm not sure what the best way is of going about it, but duplicating data isn't a good idea.

Thinking about it again, I am wondering what the primary key of the Word table is. Would it be the first column, the Nominative Singular or what have you? Then again I do not know whether the Nominative Singular of a word never has variations. I see no reason for it to be so. So I doubt it is a good primary key.

Then again, there are two other things I don't know: is there always a "preferred" variant for each form of the word, a default variant? And do the variants in each form of the word correspond to one another? i.e. if a speaker uses variant no. 2 of the "dative plural" then can they be expected to use variant no. 2 of the "vocative plural"? Presumably not, since in the example word you linked, the "vocative singular" has a different number of variants to the "vocative plural" (and neither is equal to 1). This being the case, I don't see the case for having a table with 12 columns and filling rows with column-values that don't relate to one another. (That is, putting 'dive' in putative column VocativeSingular and in the same row putting 'di' in column VocativePlural - despite the fact that these two variants do not directly relate to one another.)

I am thinking of a solution that looks something like this: (Perhaps I am going OTT on tables, and the Singular/Plural and Cases would be better hard-coded. You will have to decide that.)

code:
CREATE TABLE GrammaticalNumber (
    GrammaticalNumberID SMALLINT NOT NULL,
    Name CHAR(8) CHARACTER SET ascii NOT NULL,
    PRIMARY KEY (GrammaticalNumberID)
);

INSERT INTO
    GrammaticalNumber
    (GammaticalNumberID, Name)
VALUES
    (1, 'Singular'),
    (2, 'Plural');

CREATE TABLE GrammaticalCase (
    GrammaticalCaseID SMALLINT NOT NULL,
    Name CHAR(10) CHARACTER SET ascii NOT NULL
    PRIMARY KEY (GrammaticalCaseID)
);

INSERT INTO
    GrammaticalCase
    (GrammaticalCaseID, Name)
VALUES
    (1, 'Nominative'),
    (2, 'Genitive'),
    (3, 'Dative'),
    (4, 'Accusative'),
    (5, 'Ablative'),
    (6, 'Vocative');

CREATE TABLE WordVersion (
    WordID INT NOT NULL,
    GrammaticalNumber SMALLINT NOT NULL,
    GrammaticalCase SMALLINT NOT NULL,
    VariationNumber SMALLINT NOT NULL,
    Word VARCHAR(99) CHARACTER SET utf8 NOT NULL,
    PRIMARY KEY (WordID, GrammaticalNumber, GrammaticalCase, VariationNumber)
);

(GrammaticalNumber and GrammaticalCase are both foreign keys. I am not adding
the declaration to the above CREATE TABLE statement because I can never
remember what the proper syntax is for the flavour of SQL I actually use,
never mind what the proper syntax is for ANSI SQL.)

INSERT INTO
    WordVersion
    (WordID, GrammaticalNumber, GrammaticalCase, VariationNumber, Word)
VALUES
    (1, 1, 1, 1, 'deus'),
    (1, 1, 2, 1, 'de&#299;'),
    (1, 1, 3, 1, 'de&#333;'),
    (1, 1, 4, 1, 'deum'),
    (1, 1, 5, 1, 'de&#333;'),
    (1, 1, 6, 1, 'deus'),
    (1, 1, 6, 2, 'dive'),
    (1, 2, 1, 1, 'de&#299;'),
    (1, 2, 1, 2, 'd&#299;'),
    (1, 2, 1, 3, 'di&#299;'),
    (1, 2, 2, 1, 'de&#333;rum'),
    (1, 2, 2, 2, 'deum'),
    (1, 2, 3, 1, 'd&#299;s'),
    (1, 2, 3, 2, 'de&#299;s'),
    (1, 2, 3, 3, 'di&#299;s'),
    (1, 2, 4, 1, 'de&#333;s'),
    (1, 2, 5, 1, 'd&#299;s'),
    (1, 2, 5, 2, 'de&#299;s'),
    (1, 2, 5, 3, 'di&#299;s'),
    (1, 2, 6, 1, 'de&#299;'),
    (1, 2, 6, 2, 'd&#299;'),
    (1, 2, 6, 3, 'di&#299;');
Notice here that WordVersion.WordID might or might not be a foreign key. If you capture no further information about a word than what its various forms are, it need not strictly be a foreign key to another table. If you have a table recording data such as the meaning of a word, first recorded use, or whatever then it does need to be a foreign key. I used a number for WordID, but equally sensible would be to use the word itself, provided that you can choose a canonical version of the word to serve this purpose.

edit: The forum ate my copy-pasted accented characters from the Wiktionary page.

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
That's actually a very elegant and clever solution. There is no guarantee that any instance of a word (for e.g. deum, the nom. sg. of the word) is unique and could not be replicated in another word -- you'd be able to figure out the meaning based on context and usage, so there is chance for a double up of words in the table, so having an incremental numeric semi-unique ID is the best solution -- as you've done, "1, 1, 1, 1, deus".

It also opens up the possibility of just adding a supplementary column to the WordVersion table if I want to add references to more information, such as etymology or anything like that -- it can just be empty for most words, but where extra info exists, it can have a pointer to a separate table with that info.

I'm going to whack that in now and see how it goes, thanks a lot :)

Edit: I'd be best off making the 'Word' column itself the only index in all that, right? Because I'll need to do look-ups for a specific word and then I can grab all the entries with that same ID.

Editx2: In fact, I don't need the foreign keys or those two other tables at all, do I? They're just there to ensure structural conformity and clarify the definitions, but since I'm the only one who will be dealing with this database or the code, I can make do with just the WordVersion table, no foreign key references, and just ensure I have a good commenting/documentation system so I understand what the '1, 1, 2, 1' means..

Sulla Faex fucked around with this message at 09:42 on Apr 8, 2012

Gilgamesh
Nov 26, 2001

EDIT: Got it, see bottom

I can't figure out where my query is going wrong. I feel like I'm missing something stupid.

code:
SELECT * 
FROM   dl_item AS c, 
       dlp_item AS ci 
       LEFT JOIN dl_battlestats AS b 
         ON b.cardid = c.id 
            AND b.cardtype = 'item' 
       LEFT JOIN dlp_battlestats AS bi 
         ON bi.cardid = ci.id 
            AND bi.cardtype = 'item' 
WHERE  c.id = 19 
       AND ci.itemid = c.id
The purpose is to definitely get a join of dl_item and dlp_item, and then pick up the respective dl_battleStats and dlp_battleStats, if they exist.

Error: #1054 - Unknown column 'c.id' in 'on clause'

Here are the relevant table structures:

code:
CREATE TABLE IF NOT EXISTS `dl_item` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique identifier',
  `variant` smallint(5) unsigned NOT NULL COMMENT 'links to dl_variant',
  `name` varchar(50) NOT NULL,
  `cardText` text NOT NULL,
  `itemType` enum('item','ally') NOT NULL,
  `cost` tinyint(4) NOT NULL,
  `category` varchar(10) NOT NULL COMMENT 'main category, like armor, weapon, artifact',
  `subcategory` varchar(10) NOT NULL COMMENT 'secondary catagory, like mace, instrument, belt, rune',
  `quantity` smallint(5) unsigned NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='A list of itemtypes' AUTO_INCREMENT=76 ;

CREATE TABLE IF NOT EXISTS `dlp_item` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `boardid` int(11) NOT NULL,
  `itemid` int(11) NOT NULL,
  `deckOrder` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=59 ;

CREATE TABLE IF NOT EXISTS `dl_battleStats` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'unique ID',
  `cardType` enum('player','adventure','item') NOT NULL COMMENT 'type of card',
  `cardid` int(10) unsigned NOT NULL COMMENT 'links to the player/encounter/ally',
  `maxHealth` tinyint(3) unsigned NOT NULL COMMENT 'life',
  `maxStamina` tinyint(3) unsigned NOT NULL COMMENT 'stamina',
  `melee` tinyint(3) unsigned NOT NULL COMMENT 'melee',
  `meleeDamage` tinyint(3) unsigned NOT NULL COMMENT 'melee damage',
  `ranged` tinyint(3) unsigned NOT NULL COMMENT 'ranged',
  `rangedDamage` tinyint(3) unsigned NOT NULL COMMENT 'ranged damage',
  `magic` tinyint(3) unsigned NOT NULL COMMENT 'magic',
  `magicDamage` tinyint(3) unsigned NOT NULL COMMENT 'magic damage',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=98 ;

CREATE TABLE IF NOT EXISTS `dlp_battleStats` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'unique ID',
  `cardType` enum('player','adventure','item') NOT NULL COMMENT 'type of card',
  `cardid` int(10) unsigned NOT NULL COMMENT 'links to the player/encounter/ally',
  `health` tinyint(3) unsigned NOT NULL COMMENT 'life',
  `stamina` tinyint(3) unsigned NOT NULL COMMENT 'stamina',
  `meleeMod` tinyint(3) unsigned NOT NULL COMMENT 'melee',
  `meleeDamageMod` tinyint(3) unsigned NOT NULL COMMENT 'melee damage',
  `rangedMod` tinyint(3) unsigned NOT NULL COMMENT 'ranged',
  `rangedDamageMod` tinyint(3) unsigned NOT NULL COMMENT 'ranged damage',
  `magicMod` tinyint(3) unsigned NOT NULL COMMENT 'magic',
  `magicDamageMod` tinyint(3) unsigned NOT NULL COMMENT 'magic damage',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
In english, dl_item and dl_battleStats are both essentially static tables that contain the base stats of a card. dl_battleStats can link to an item, a player, or an adventure (in this case, we're looking at items). If the item is an ally instead of a regular item, it will have a battleStats field. If it's a regular item, it won't.

dlp_item and dlp_battleStats are basically echos of those two tables, but they're for specific game instances. So I'm trying to get a query that would give me all the current as well as static stats (and battle stats, if they exist) given an item id.

EDIT: Turns out I haven't done much mysql 5 programming. It's a little more fussy about joins. Fixed code is:

code:
SELECT * 
FROM   dl_item AS c 
       INNER JOIN dlp_item AS ci 
         ON c.id = 19 
            AND ci.itemid = c.id
       LEFT JOIN dl_battlestats AS b 
         ON b.cardid = c.id 
            AND b.cardtype = 'item' 
       LEFT JOIN dlp_battlestats AS bi 
         ON bi.cardid = ci.id 
            AND bi.cardtype = 'item' 

Gilgamesh fucked around with this message at 15:51 on Apr 8, 2012

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine
Bumping this question again because I have to think there's a way around this, right?

quote:

We have our main MySQL server in Wisconsin. We have the bulk of our customer service staff in Iowa. The CS staff is complaining that the connection is too slow to the server, which makes sense - the queries are hefty and the page is overlarge. Both of these can be remedied, but there's also wondering if we could change our MySQL topology. The options seem to be:
1) Have them go out over the public internet instead of our direct link between cities; that way, ping might be longer but they aren't competing with the VOIP traffic between cities
2) Cluster the database so that writes and reads can happen simultaneously on local servers in both cities.

#2 is much preferable, but as you can probably tell by my description I have absolutely no clue how to implement it or even if it is 'clustering.' The best I could find for MySQL Cluster is that it would require using NDB tables and I'd rather not convert our entire database to that. What are my options here? Thanks.

We already replicate from the master in Wisconsin to a slave in Iowa, but the staff need full read/write access to the data, so that's not a huge boon. Master-Master setups are apparently difficult to pull off in MySQL? Any ideas?

epswing
Nov 4, 2003

Soiled Meat


When attempting to set the cascade action to Set Null for both these associations, SQL Server 2008 R2 says

Unable to create relationship 'FK_Cars_Drivers_Secondary'.
Introducing FOREIGN KEY constraint 'FK_Cars_Drivers_Secondary' on table 'Cars' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.


I've read but don't quite understand http://stackoverflow.com/questions/851625/foreign-key-constraint-may-cause-cycles-or-multiple-cascade-paths

I don't see any cycles here, so it must be a "multiple cascade path". If a Driver is deleted, what harm is setting PrimaryDriverId and SecondaryDriverId to null?

Sub Par
Jul 18, 2001


Dinosaur Gum
I have a non-technical database question. I work for a small company with 10 employees, looking to hire an 11th. We do marketing and analytical consulting for non-profits and are looking for an entry level person with some experience using SQL Server to work on some basic ETL stuff and pulling together some custom datasets in response to ad hoc client requests.

I didn't anticipate having a hard time finding this person to be honest, but we've gone a month with only one promising lead. So my questions is, where do you guys typically look for new hires/where do you advertise the position? Most places people point me are mostly geared toward application developers/web developers. Where can I find recent MIS grads or even people with an Econ or stats degree who know how to write some SQL?

spiritual bypass
Feb 19, 2008

Grimey Drawer
I don't understand. Are you only finding developers who are bad at databases for some reason? That data retrieval you described can certainly turn into a full-time development type of thing depending on how your database is laid out, what new stuff you add to it, and how fickle your clients are. I've worked with a "data analyst" before and now I would certainly not deal with anyone who claimed to understand databases and SQL without knowing the rest of the story on contemporary business programming.

But to answer your question, I always use Craigslist and it works fine. The trouble you'll find anywhere is that 3/4 resumes drastically overstate people's abilities and the only way to tell is to bring them in for an interview.

Sub Par
Jul 18, 2001


Dinosaur Gum
We're finding application developers who will be absolutely bored to tears in this job. We need the "data analyst" who wants to spend most of their time writing SQL at the start and transition into cube development/maintenance and more BI-type stuff.

Instead, we're getting either liberal arts people with 0 technical skills, or people who list experience with C#, Java, C++, etc. And hey, that would be great! But they go on to talk about all of the cool applications they have developed/want to develop. That's not what we do.

Thanks for the suggestion though, we were waiting to post on Craigslist but I guess we might as well!

Powdered Toast Man
Jan 25, 2005

TOAST-A-RIFIC!!!
Is a "link table" the only way to handle a many-to-many relationship? I'm creating a database to keep track of job title <--> active directory group membership information and that's obviously many-to-many.

I'm also a bit stuck on how to process the information I have available to get it into the database. Presently, it resides in a crappy Excel workbook. It is easily exported, but the relationships are another matter. Right now the Excel workbook keeps track of those by using a hidden sheet that has a column for each job title, and then each group that is associated with that title is listed under that column (with the title itself at the top). I'm planning to go from Excel 2007 to Access 2007...it's what I have available and I have some experience with Access, so whatever. Any ideas?

Pardot
Jul 25, 2001




Powdered Toast Man posted:

Is a "link table" the only way to handle a many-to-many relationship? I'm creating a database to keep track of job title <--> active directory group membership information and that's obviously many-to-many.

It may not be the only way, but it's the best way. They are also known as a "join tables". Also it's a good for storing meta data on the relationship itself in that table, such as when it was created, who it was created by, etc.

zyang31
Oct 26, 2007
I have two tables, both which have lists of dates something like this:

Table1 has multiple days in a row

Jan.1
Jan.2
Jan.3
.
.
.

The second table just has random days that jump around

Jan.5
Jan.12
Jan.18
.
.
.

I'm trying to join the tables by closest date after the date in table1. So the output would be something like this

T1Date T2Date
Jan1 Jan5
Jan2 Jan5
Jan3 Jan5
Jan4 Jan5
Jan5 Jan5
Jan6 Jan12
.
.
.
Jan12 Jan12
Jan13 Jan18
.
.
.
etc.

My code is something like
code:
CREATE TABLE t1 (
Day DATETIME
)

INSERT INTO t1(Day)
SELECT 
('20110505') UNION ALL
SELECT
('20110506') UNION ALL
SELECT
('20110507') UNION ALL
SELECT
('20110508') UNION ALL
SELECT
('20110509')  UNION ALL
SELEcT
('20110510' )

CREATE TABLE t2 (
Day DATETIME 
)

INSERT INTO t2(Day)

SELECT
('20110507') UNION ALL

SELECT
('20110509')  UNION ALL
SELEcT
('20110510' )

SELECT t1.Day, t2.Day FROM t1 INNER JOIN t2 on t1.Day = 
          DATEADD(D,DATEDIFF(D,t2.Day,t1.Day), 

          (SELECT TOP 1 t2.Day FROM t1 CROSS JOIN t2 
                  
                 WHERE DATEDIFF(D,t1.Day,t2.Day) >= 0 ORDER BY DATEDIFF(D,t1.Day,t2.Day)))

                               /* I'm using Sql server in case you haven't guessed from the select top 1 statement */
Unfortunately, it's not working and I'm not exactly sure why. It's running but yielding the wrong results.


quote:

Day Day
2011-05-05 00:00:00.000 2011-05-07 00:00:00.000
2011-05-06 00:00:00.000 2011-05-07 00:00:00.000
2011-05-07 00:00:00.000 2011-05-07 00:00:00.000
2011-05-08 00:00:00.000 2011-05-07 00:00:00.000
2011-05-09 00:00:00.000 2011-05-07 00:00:00.000
2011-05-10 00:00:00.000 2011-05-07 00:00:00.000
NULL 2011-05-09 00:00:00.000
NULL 2011-05-10 00:00:00.000



My guess is that this line
code:
 SELECT TOP 1 t2.Day FROM t1 CROSS JOIN t2 
                  
                 WHERE DATEDIFF(D,t1.Day,t2.Day) >= 0 ORDER BY DATEDIFF(D,t1.Day,t2.Day) 

is only running once and isn't updating every time SQL goes over to the next date. So it starts at 05/05/2011 and selects 05/07/2011 for the second column. However, when it gets to 05/09/2011, the line of code isn't rerunning and so it doesn't select 05/09/2011 for the second column.

edit in response to below post:
The line with the two ambiguous D's: WHERE DATEDIFF(D,t1.D,t2.D) >= 0 ORDER BY DATEDIFF(D,t1.D,t2.D)))

Those two ambiguous D's aren't actually variables, but just telling SQL to subtract and add by days. I'll rename the D's into "Day" so they're less confusing.

zyang31 fucked around with this message at 15:17 on Apr 11, 2012

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

zyang31 posted:

Unfortunately, it's not working and I'm not exactly sure why
Any help?

What does "it's not working" mean? Does it give an error message? Does it do something without complaining, but yield the wrong results?

Your last query refers to columns called D a lot. In some places you have specified the table but in others you have not, for example

DATEADD(D,DATEDIFF(D,t1.D,t2.D)

contains two D's which are ambiguous because it's not clear what table they are from.

Bob Morales
Aug 18, 2006


Just wear the fucking mask, Bob

I don't care how many people I probably infected with COVID-19 while refusing to wear a mask, my comfort is far more important than the health and safety of everyone around me!

What do you do when a customer wants your web app database encrypted (to meet HIPAA standards) when you don't even store HIPAA data?

It's a big enough account where it makes more sense to just do what they want instead of arguing with them about how it's bullshit.

Option 1 is not giving Rackspace access to our servers. Which would be fine except that's the whole point of having managed servers.

Option 2 is 'encrypting the database'. I proposed keeping the mySQL database on an encrypted partition on the server (CentOS), but they want it so someone can't do a 'select *' and just get a huge dump of all the data.

We keep the data for multiple websites on the same server, and each website can only access the database for that server, but we don't have access whittled down per customer. So even though our web app only returns data for your employees if you run a report, there's nothing in the DB preventing that.

Rackspace offers this but I don't know if that's what we want:

http://www.rackspace.com/cloud/tools/applications/gazzang-ezncrypt/

JeansW
Aug 4, 2004
Yes. Like the jeans...

zyang31 posted:

I have two tables, both which have lists of dates something like this:

Table1 has multiple days in a row

Jan.1
Jan.2
Jan.3
.
.
.

The second table just has random days that jump around

Jan.5
Jan.12
Jan.18
.
.
.

I'm trying to join the tables by closest date after the date in table1. So the output would be something like this

T1Date T2Date
Jan1 Jan5
Jan2 Jan5
Jan3 Jan5
Jan4 Jan5
Jan5 Jan5
Jan6 Jan12
.
.
.
Jan12 Jan12
Jan13 Jan18
.
.
.
etc.

My code is something like
code:
CREATE TABLE t1 (
Day DATETIME
)

INSERT INTO t1(Day)
SELECT 
('20110505') UNION ALL
SELECT
('20110506') UNION ALL
SELECT
('20110507') UNION ALL
SELECT
('20110508') UNION ALL
SELECT
('20110509')  UNION ALL
SELEcT
('20110510' )

CREATE TABLE t2 (
Day DATETIME 
)

INSERT INTO t2(Day)

SELECT
('20110507') UNION ALL

SELECT
('20110509')  UNION ALL
SELEcT
('20110510' )

SELECT t1.Day, t2.Day FROM t1 INNER JOIN t2 on t1.Day = 
          DATEADD(D,DATEDIFF(D,t2.Day,t1.Day), 

          (SELECT TOP 1 t2.Day FROM t1 CROSS JOIN t2 
                  
                 WHERE DATEDIFF(D,t1.Day,t2.Day) >= 0 ORDER BY DATEDIFF(D,t1.Day,t2.Day)))

                               /* I'm using Sql server in case you haven't guessed from the select top 1 statement */
Unfortunately, it's not working and I'm not exactly sure why. It's running but yielding the wrong results.


My guess is that this line
code:
 SELECT TOP 1 t2.Day FROM t1 CROSS JOIN t2 
                  
                 WHERE DATEDIFF(D,t1.Day,t2.Day) >= 0 ORDER BY DATEDIFF(D,t1.Day,t2.Day) 

is only running once and isn't updating every time SQL goes over to the next date. So it starts at 05/05/2011 and selects 05/07/2011 for the second column. However, when it gets to 05/09/2011, the line of code isn't rerunning and so it doesn't select 05/09/2011 for the second column.

edit in response to below post:
The line with the two ambiguous D's: WHERE DATEDIFF(D,t1.D,t2.D) >= 0 ORDER BY DATEDIFF(D,t1.D,t2.D)))

Those two ambiguous D's aren't actually variables, but just telling SQL to subtract and add by days. I'll rename the D's into "Day" so they're less confusing.
I'm just about positive there's an easier way to do this with CTE's but I'm too tired to think right now.

This correlated subquery works though.
code:
SELECT t1.Day, t2.Day 
FROM #1 as t1 
	INNER JOIN t2 as t2 on t1.Day = DATEADD(D,DATEDIFF(D,t2.Day,t1.Day), 
          (SELECT TOP 1 t4.Day FROM t1 as t3 INNER JOIN t2 as t4 ON t3.Day = t1.Day  WHERE DATEDIFF(D,t3.Day,t4.Day) >= 0 ORDER BY DATEDIFF(D,t3.Day,t4.Day)))

Jethro
Jun 1, 2000

I was raised on the dairy, Bitch!

Hammerite posted:

What does "it's not working" mean? Does it give an error message? Does it do something without complaining, but yield the wrong results?

Your last query refers to columns called D a lot. In some places you have specified the table but in others you have not, for example

DATEADD(D,DATEDIFF(D,t1.D,t2.D)

contains two D's which are ambiguous because it's not clear what table they are from.
The D in the context of the first argument to DATEADD and DATEDIFF refers to the "Day" part of the date, not a column named D.

EDIT: Oh, zyang31 already responded to that.

Jethro fucked around with this message at 17:21 on Apr 11, 2012

revmoo
May 25, 2006

#basta
What would be the syntactically correct way to write this:

SELECT * FROM atable WHERE (open_date BETWEEN '2012-01%' AND '2012-02%')

EDIT: got it. SELECT * FROM atable WHERE (open_date >= '2012-01%' AND open_date <= '2012-02%')

revmoo fucked around with this message at 17:38 on Apr 11, 2012

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Bob Morales posted:

What do you do when a customer wants your web app database encrypted (to meet HIPAA standards) when you don't even store HIPAA data?

HIPAA doesn't require encryption of the database - it's sufficent to implement SSL if you have a web facing service.

DankTamagachi
Jan 20, 2005
Tamagachi to your throat!

revmoo posted:

What would be the syntactically correct way to write this:

SELECT * FROM atable WHERE (open_date BETWEEN '2012-01%' AND '2012-02%')

EDIT: got it. SELECT * FROM atable WHERE (open_date >= '2012-01%' AND open_date <= '2012-02%')

Could you just do select * from atable where open_date >= '2012-01-01' and open_date < '2012-03-01'

This seems a bit more clear, if it accomplishes the same thing.

Adbot
ADBOT LOVES YOU

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

hieronymus posted:

HIPAA doesn't require encryption of the database - it's sufficent to implement SSL if you have a web facing service.

There's different levels involved, though I went through a similar go-round with PCI compliance and encryption. Luckily for PCI if you simply don't store things you shouldn't be storing anyway (e.g. CCN, CVV, DOB) you can get away with writing the other PIN stuff (fname, lname, address1, etc.) to db if you're always using SSL when collecting/communicating. Not sure if HIPAA gives you that kind of out though.

Don't know how much you've talked to your Rackspace guy but they were somewhat helpful on the documentation side. Their bona fides from the various certification agencies are legit, not sure if that'll help. I had to collect information about how they restrict access to the servers, have 24 hour video recordings of the racks, biometric pre-scheduled access only, etc.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply