6
votes

Commande entier multi-colonnes

Je ne sais pas si j'ai choisi le titre approprié pour cette question (sinon, veuillez le modifier en conséquence) mais envisagez la structure de table simplifiée suivante que je travaille avec:

---------------------------------------------------------------------------------
  date  |  temperature  |  humidity  |  pressure  |  windSpeed  |  moonDistance  
---------------------------------------------------------------------------------
 090206 |  7            |  87        |  998.8     |  3          |  363953        
---------------------------------------------------------------------------------
 ...... |  ...          |  ...       |  ....      |  ...        |  ......        
---------------------------------------------------------------------------------
 100206 |  10           |  86        |  1024      |  2          |  386342        
---------------------------------------------------------------------------------
 100207 |  9            |  90        |  1015      |  1          |  391750        
---------------------------------------------------------------------------------
 100208 |  13           |  90        |  1005      |  2          |  396392        
---------------------------------------------------------------------------------
 100209 |  12           |  89        |  1008      |  2          |  400157        
---------------------------------------------------------------------------------
 100210 |  11           |  92        |  1007      |  3          |  403012        
---------------------------------------------------------------------------------
 100211 |  6            |  86        |  1012      |  2          |  404984        
---------------------------------------------------------------------------------
 100212 |  6            |  61        |  1010      |  3          |  406135        
---------------------------------------------------------------------------------
 100213 |  7            |  57        |  1010      |  2          |  406542        
---------------------------------------------------------------------------------


3 commentaires

Une question de barrière de la langue, pouvez-vous expliquer ce que vous voulez dire toutes les valeurs dans son ensemble et donner plus d'exemple avec d'autres gammes comme 100-1000


@ Pentium10: J'ai mis à jour ma question pour adresser votre commentaire, veuillez vérifier à nouveau, merci. =)


Merci. Vous avez fait un très bon travail. Comme vous avez mentionné la note des données météorologiques, c'est un peu difficile. Voir ma réponse mise à jour ci-dessous.


4 Réponses :


3
votes

Je pense que c'est possible. Essayez d'utiliser une fonction qui ajoute la différence. Par exemple:

Sélectionnez *, ABS (I - @i) + ABS (J - @J) + ABS (K - @k) + ABS (x - @x) + ABS (Y - @y) + ABS (Z - @z) De la table

Cela vous donnera votre valeur de différence logique floue. Le plus bas, plus le match est proche. Vous devriez également être capable de trier par cette expression: c.-à-d. Commander par ABS (I - @i) ... ASC

Quelques suggestions, sélectionnez peut-être les résultats à une table Temp et trier sur ceci.

Alternativement, si vous utilisez SQL Server, examinez-le à l'aide de la CLR .NET et de le faire dans un ensemble .NET - cela vous donnera plus de puissance et d'options. Il vous permettra également de fixer plus facilement du poids à certains champs (si vous voulez dire que certains champs doivent avoir une pondération supplémentaire).

J'espère que cela aide, Steve


8 commentaires

Cette requête revient simplement null pour moi. Il marqua mysql.


Salut, désolé - oui, il l'a fait. Donc, CLR est sorti. Cependant, MySQL a également la fonction ABS. N'oubliez pas que si l'une des valeurs est nulle, toute l'expression sera null. Donc, si vous ne voulez pas que les valeurs nulles comptent: coalesce (ABS (I-@ I), 0) + .... Pour chaque expression - alors les nulls seront traités comme 0. Alternativement, vous pouvez mettre un nombre plus élevé là-bas pour que les nuls diminuent la pertinence - par exemple, la coalesce (ABS (I-@ i), 10) ... Selon ce que vous voulez réaliser. J'ai supposé qu'il n'y aurait pas de nulls dans ces données - désolé.


Quel ABS (I-@ i) Supposons faire? Je ne reçois pas cet opérateur @ là-bas.


@ Pentium10: @i est une variable que vous pouvez définir.


@MRCRAZAZE: +1 Cependant, l'utilisation de votre solution ne serait pas le Moondistance à peu près toutes les autres valeurs non pertinentes? En outre, vous avez mentionné de pondérer les colonnes, pourriez-vous me donner une suggestion sur les facteurs à utiliser dans mes données météorologiques? Merci.


Salut Alix, merci pour des commentaires positifs. En ce qui concerne la pondération, vous considérez peut-être que vous considérez la température comme le facteur le plus important afin que cela puisse être regroupant (ABS (I-@ i)) * 10, ce qui signifie que les différences de température donneraient un nombre plus élevé et donc moins de pertinence. L'inverse pourrait être fait pour dire que la pression - peut-être diviser la différence de 10, ou tout ce qui est le plus adapté. Une logique similaire pourrait être utilisée pour réduire la pertinence de la moonistance. Un analyste météo décidait mieux que :) J'espère que cela vous aidera!


@MRCRAZAZE: J'espérais une solution pouvant analyser les valeurs dans son ensemble, car je ne sais pas ce qui constitue une plus grande importance.


Salut Alix, je pense que pentium10 est sur la bonne voie. Je sélectionnerais l'écart type de toutes les valeurs d'abord dans les variables pour accélérer la requête, puis diviser la différence entre la date actuelle et celle de la requête par l'écart type, les ajoutant ensemble pour chaque élément. Par exemple. Sélectionnez @idev = stddev (i), @jdev = stddev = stddev (j) ... puis sélectionnez *, grade (ABS (I- @ i) / @ iRDV) + (ABS (J- @ J) / @ JDev). .. à partir de la commande de table par (ABS (I-@ i i) / @ iDV) + (ABS (J- @ J) / @ jDev) ... Cela ajoutera le nombre d'écarts types Chaque valeur est à partir du paramètre spécifié ( c'est-à-dire aujourd'hui) - donner une meilleure pondération



1
votes

Je ne suis pas sûr que cela soit pertinent ou pas à la question, mais certaines valeurs (i, j, k) signifie plus c'est mieux alors que autres valeurs (x, y, z) signifie la En face: moins c'est mieux.

Depuis que vous avez affaire à des dates, vous voudrez peut-être dériver d'autres dates en fonction de ces critères.
Par exemple, vous pouvez calculer de nouvelles dates, pour une valeur comportant un effet plus élevé vous ajoutez quelques heures / jours / semaines / mois à votre date, et si une valeur comporte un effet d'amant Vous n'ajoutez que quelques secondes / minutes à vos dates. Ensuite, vous triez en fonction de cette nouvelle date calculée.
Vous pouvez soustraire des dates à l'aide de compensations négatives si elles atteignent un niveau de crête

Vérifiez FUZZY SQL ( FSQL )

EDIT 1

Essayez ceci: std (i) * abs (i- @ i) ... xxx


6 commentaires

Je n'ai pas connu MySQL avait une fonction intégrée STD (), merci. Deux questions: 1) ne serait-elle pas une requête plus favorable (en termes de tri) à la colonne i ( v1 )? 2) Pourquoi triez-vous V1 ASC et V2 Desc?


J'ai dû utiliser la valeur calculée car elle diffère si, par exemple, vous définissez: 10 que i . Et avec ASC et Desc Je voulais souligner que certaines colonnes ont une commande différente. Si la température est égale, une humidité plus élevée est meilleure. Mysql a également variance () .


@ Pentium10: Merci, concernant la première question que j'ai posée, je ne faisais pas référence à l'utilisation des valeurs calculées, mais à l'ordre de la commande par clause elle-même. Ne devrait pas commander MySQL par v1 ou uniquement commander par v2 s'il y a deux valeurs ou plus v1 avec le même "classement" / commande ?


Les commandes MySQL par V1 principalement et uniquement commandes par V2 S'il existe deux valeurs v1 ou plus avec le même classement. C'est vrai. Commander par V1 ASC, V2 DESC


@ Pentium10: Dans ce cas, cela ne parviendra pas à commander par toutes les valeurs dans son ensemble. = \


Ouais ça va. Cependant, je pense que vous aide à obtenir des réponses, jusqu'à ce que vous trouviez une formule de travail pour calculer une valeur de tous.



6
votes

Le problème que vous semblez avoir est que chaque colonne a une échelle différente et vous ne pouvez donc pas les combiner facilement. Ce problème peut être résolu en utilisant une technique appelée blanchiment. Cela implique de calculer l'écart moyen et standard de chaque colonne (vous pouvez le faire dans 1 instruction SQL), puis une réfinancement de chaque colonne à ceci lors de la sélection:

SELECT
    date,
    i,
    j,
    k,
    SQRT( POW((i-@iMean)/@iStdDEv, 2) + POW((j-@jMean)/@jStdDEv, 2) + POW((k-@kMean)/@kStdDEv, 2) )
AS
    sort_order
FROM
    table
ORDER BY
    sort_order


5 commentaires

Je pense avoir commis une erreur dans ma SQL, la distance euclidienne que j'ai déclarée ne vous donnerait que la plus proche de la moyenne, si vous souhaitez comparer avec une ligne particulière, vous auriez besoin de la distance à ce sujet: SQRT (pow (@Atarget - ((i- @ iman) / @ istddev), 2) + POW (@jTarget - ((J- @ JMEAN) / @ JSTDDEV), 2) + POW (@ktarget - (k- @ kean) / @ kstddev, 2)) Bien sûr, les valeurs blanchies peuvent être pré-calculées dans le tableau, puis vous pourriez faciliter cela.


Salut neel, réponse vraiment intéressante - je me demande pourquoi chaque résultat est carré puis le carré total enraciné? Aussi, est-il nécessaire d'utiliser la moyenne du tout - j'ai essayé de résoudre en utilisant ((@itarget - i) / @ istddev) - vous donnant la mesure de la distance entre eux dans le nombre d'écarts types.


Vous voulez faire cela pour obtenir la distance entre le point qui vous intéresse au point que vous êtes. Pensez à un triangle coudé droit, à obtenir la distance entre (x1, y1) sur (x2, y2), vous trouvez l'hypoténuse qui est SQRT ((x1-x2) ^ 2 + (y1-y2) ^ 2). En 3D (x, y, z), cela devient sqrt ((x1-x2) ^ 2 + (y1-y2) ^ 2 + (z1-z2) ^ 2). Pensez à vos colonnes sous forme d'axes sur un graphique, les points les plus similaires seraient spacieux. Plus vous avez à considérer des colonnes que vous avez les dimensions. Votre intuition à faire ((@Atarget - i) / @ istddev) est correcte car cela mesurera la distance à une cible.


Comme MrCraze a déclaré que c'était une réponse vraiment intéressante, je vais l'essayer dans quelques heures et poster mes commentaires ici - Concernant Weka: Cela ressemble à un très bon projet (j'utiliserais en fait "les outils d'apprentissage des machines pratiques et Techniques "Réservez par les mêmes auteurs de temps en arrière) mais je pense que je manque les compétences en mathématiques pour bien comprendre comment l'utiliser.


@Alix s'intéressera aux résultats, j'ai des idées sur la manière dont vous pourriez le faire de manière précalculée pour vous permettre de faire des sorties arbitraires, mais vous retiendrez pour voir si cela fonctionne pour vous.



1
votes

C'est difficile (sinon impossible) à faire en SQL, mais il existe une technique d'analyse multivariée appelée analyse factorielle. C'est une façon de créer un "facteur" - une combinaison linéaire de vos variables qui met un poids sur chaque entrée pour obtenir un "score de facteur". Fondamentalement, il fait un tas de manipulations algébriques linéaires sur vos données pour créer un ensemble de scores simples qui minimise certains objectifs (comme des erreurs totales).

J'ai une analyse factorielle sur 3 jours de données météorologiques horaires et il semble très bon. Vous pouvez voir que les entrées avec des scores de facteur similaires sont généralement très proches des valeurs des quatre mesures. J'ai utilisé une composante principale extraction avec une rotation Equimax: xxx


1 commentaires

Semble intéressant et peut-être assez utile pour l'essayer, pouvez-vous me procurer d'autres informations sur la méthode d'analyse des facteurs que vous avez mentionnée?