0
votes

Convertir une chaîne de yyyymm en date aaaaa-mm-jj avec jour 1

J'ai cette colonne startmmonth des tables, qui aime ceci: yyyymm , donc 201801 , 201707 etc.

Je veux cette colonne à mon avis que je crée, mais que je crée, mais converti en une date, comme aaaa-mm-mm-dd avec la journée comme le premier du mois, alors ** 201801> 2018-01-01 et 201707> 2017-07-01. **

Je continue à obtenir l'erreur:

La conversion a échoué lors de la conversion de la date et / ou du temps de caractère chaîne.

Quelqu'un peut-il m'aider?

J'ai essayé ceci: xxx


6 commentaires

Êtes-vous sûr que c'est mysql?


Votre code fonctionne bien pour moi avec 102 et 112 comme type lors de l'utilisation d'une chaîne de code papier au lieu de la colonne (I.E '201811'). Quel type est démarrage? Pourrait-il contenir des espaces?


Remarque, la date DataType n'a pas de format; Date (heure) Les fichiers de données sont stockés comme une représentation binaire. Votre couche de présentation choisit le format La date est affichée dans (par exemple, SSMS utilise AAAAYY-MM-DD Par défaut pour la plupart des utilisateurs).


@ Joakimdanielson Nope, pas d'espaces. Quand j'essaie de le convertir avec 'de billing_subscription s' (donc sans les jointures), cela fonctionne très bien, alors je ne comprends pas bien pourquoi cela ne fonctionnera pas lors de l'ajout de certaines jointures.


Ajoutez les résultats pour Sélectionnez StartMonth à partir de facturation_subscription où TRY_CONVERT (Date, Concat (StartMonth, '01 ')) est NULL et STARTMONTH n'est pas NULL; . Je soupçonne que vos données ne sont pas comme toutes dans le format yyyymm .


Je suis d'accord aussi bien, bien que le code de style 102 est défini comme yyyy.mm.dd , il fonctionne pour '100001' à " 233012 ': dB <.Fiddle . Si nous ne pouvons pas reproduire le problème, nous ne pouvons pas vous aider.


3 Réponses :


2
votes

Essayez d'utiliser xxx

ou xxx

Cast and Convert (Transact-SQL)

Je pense mieux utiliser try_convert ici comme indiqué @Larnu: xxx

et + au lieu de < Code> Concat Pour convertir les valeurs nulelles correctement.


11 commentaires

Toujours obtenir exactement la même erreur. Ils travaillent sans les déclarations de jointure, mais pas avec les jointures.


Essayez de vérifier startmmonth + 01 à l'aide de isdate - Sélectionnez ISDate ('20120101'), ISDate ('20121301')


Le code doit fonctionner sans le paramètre de style. Vous avez simplement de mauvaises données ... 201913 , foobar etc.


@ user11299833 - Sélectionnez s. * à partir de facturation_subscription S Où est isdate (concat (S.StartMonth, '01 ')) = 0


Est l'aversion isdate , @sergeymenshov. Par exemple, Sélectionnez ISDate (2017); retourne 1, mais Sélectionnez Convert (date, 2017); échouera. try_convert est un outil bien meilleur.


@Larnu - oui, try_convert est meilleur.


@Larnu - Sélectionnez Cast ('2017' comme date), Convertir (date, '2017')


2017 , pas '2017' @Sergeymenshov


@Larnu - Oui, mais dans la question, il est Varchark non int.


Oui, mais mon point est que isdate fournit de faux positifs (et faux négatifs, comme isdate ('') renvoie 0 , mais Convertir (date, '') travaux); Tout comme isnumeric fait. Ils devraient être évités car ils ne sont pas fiables. Juste parce que isdate renvoie 1 ne signifie pas que la valeur sera capable d'être coulé / convertie, et simplement parce qu'elle renvoie 0 ne signifie pas ça ne peut pas..


@Larnu - Oui, je suis d'accord avec vous que isdate n'est pas une bonne variante. C'est obsolète.



1
votes

Le problème est que vous faites une jointure gauche sur la table avec la chaîne qui signifie qu'il peut parfois être null s'il n'y a pas de ligne correspondante pour un incident incident code>, puis la conversion échoue

Voici un moyen de résoudre ce p>

SELECT CASE WHEN s.StartMonth IS NOT NULL THEN convert(DATE, concat (s.StartMonth,'01'), 112)
       ELSE null -- Or return some default value, otherwise this row can be removed
       END  as SubscriptionStart
FROM incident i
LEFT JOIN imcustomerid cid ON i.accountid = cid.accountid
LEFT JOIN billing_subscription s ON cid.imcustomerid = s.idcustomer
LEFT JOIN billing_subscriptiontype st ON s.idsubscriptiontype = st.id


7 commentaires

Convert (date, null) retourne null . Cela ne résoudra pas le problème. try_convert arrêtera le SQL de fournir une erreur, mais peut ne pas donner aux résultats souhaités.


@Larnu Où dois-je convertir sur une valeur null?


Pour être plus court, vous pouvez sauter sinon NULL ici.


@ Sergeymenshov Je sais mais je pensais qu'il serait plus clair que vous puissiez avoir un résultat par défaut. J'aurais peut-être ajouté un commentaire.


"signifie qu'il peut parfois être nul s'il n'y a pas de ligne de correspondance pour une ligne d'incident, puis la conversion échoue" . Vous dites que convert produira une erreur si la valeur à convertir a une valeur de null ; ce n'est pas vrai. Cette requête produira toujours l'erreur que l'OP obtient en tant que cas est superflu. L'ensemble du cas pourrait être écrit comme convert (date, concat (S.StartMonth, '01 '), 112) et serait exactement le même résultat (et le serait donc Erreur, comme l'OP a clairement des valeurs qui ne sont pas dans le format yyyymm ).


Parce que le problème est la valeur de s.startmonth quand ce n'est pas null .


Selon Op, la conversion fonctionne bien sans rejoindre, cela convient à chaque rangée de cette colonne qui existe dans la table, et c'est ce que je baste sur ma réponse.



0
votes

Je pense que la méthode la plus claire est Datefromparts () Code>: XXX PRE>

La manière la plus traditionnelle est simplement de soustraire un certain nombre de jours: P>

select dateadd(day,
               (1 - day(s.StartMonth)),
               s.StartMonth
              ) as SubscriptionStart


0 commentaires